From 1800cffd3b28a9cff2ffc958e690c940659d1794 Mon Sep 17 00:00:00 2001 From: Tobi Lutke Date: Wed, 11 Mar 2026 10:22:29 -0400 Subject: [PATCH] =?UTF-8?q?Lazy=20Context=20init:=20defer=20StringScanner?= =?UTF-8?q?=20and=20@interrupts=20array=20allocation=20until=20needed\n\nR?= =?UTF-8?q?esult:=20{"status":"keep","combined=5F=C2=B5s":4299,"parse=5F?= =?UTF-8?q?=C2=B5s":3057,"render=5F=C2=B5s":1242,"allocations":26015}?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/liquid/context.rb | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/liquid/context.rb b/lib/liquid/context.rb index 376d3ea1..8eab5cc2 100644 --- a/lib/liquid/context.rb +++ b/lib/liquid/context.rb @@ -38,14 +38,13 @@ module Liquid @strict_variables = false @resource_limits = resource_limits || ResourceLimits.new(environment.default_resource_limits) @base_scope_depth = 0 - @interrupts = [] + @interrupts = Const::EMPTY_ARRAY @filters = Const::EMPTY_ARRAY @global_filter = nil @disabled_tags = Const::EMPTY_HASH - # Instead of constructing new StringScanner objects for each Expression parse, - # we recycle the same one. - @string_scanner = StringScanner.new("") + # Lazy-init StringScanner — only needed if Context#[] is called during render + @string_scanner = nil @registers.static[:cached_partials] ||= {} @registers.static[:file_system] ||= environment.file_system @@ -87,11 +86,12 @@ module Liquid # are there any not handled interrupts? def interrupt? - !@interrupts.empty? + !@interrupts.frozen? && !@interrupts.empty? end # push an interrupt to the stack. this interrupt is considered not handled. def push_interrupt(e) + @interrupts = [] if @interrupts.frozen? @interrupts.push(e) end @@ -194,7 +194,7 @@ module Liquid # Example: # products == empty #=> products.empty? def [](expression) - evaluate(Expression.parse(expression, @string_scanner)) + evaluate(Expression.parse(expression, @string_scanner ||= StringScanner.new(""))) end def key?(key)