lib/liquid/context.rb in locomotive_liquid-2.2.3 vs lib/liquid/context.rb in locomotive_liquid-2.4.1
- old
+ new
@@ -20,10 +20,12 @@
@scopes = [(outer_scope || {})]
@registers = registers
@errors = []
@rethrow_errors = rethrow_errors
squash_instance_assigns_with_environments
+
+ @interrupts = []
end
def strainer
@strainer ||= Strainer.create(self)
end
@@ -39,10 +41,25 @@
raise ArgumentError, "Expected module but got: #{f.class}" unless f.is_a?(Module)
strainer.extend(f)
end
end
+ # are there any not handled interrupts?
+ def has_interrupt?
+ !@interrupts.empty?
+ end
+
+ # push an interrupt to the stack. this interrupt is considered not handled.
+ def push_interrupt(e)
+ @interrupts.push(e)
+ end
+
+ # pop an interrupt from the stack
+ def pop_interrupt
+ @interrupts.pop
+ end
+
def handle_error(e)
errors.push(e)
raise if @rethrow_errors
case e
@@ -61,12 +78,12 @@
end
end
# Push new local scope on the stack. use <tt>Context#stack</tt> instead
def push(new_scope={})
- raise StackLevelError, "Nesting too deep" if @scopes.length > 100
@scopes.unshift(new_scope)
+ raise StackLevelError, "Nesting too deep" if @scopes.length > 100
end
# Merge a hash of variables in the current local scope
def merge(new_scopes)
@scopes[0].merge!(new_scopes)
@@ -84,21 +101,15 @@
# context.stack do
# context['var'] = 'hi'
# end
#
# context['var] #=> nil
- def stack(new_scope={},&block)
- result = nil
+ def stack(new_scope={})
push(new_scope)
-
- begin
- result = yield
- ensure
- pop
- end
-
- result
+ yield
+ ensure
+ pop
end
def clear_instance_assigns
@scopes[0] = {}
end
@@ -115,41 +126,44 @@
def has_key?(key)
resolve(key) != nil
end
private
+
+ LITERALS = {
+ nil => nil, 'nil' => nil, 'null' => nil, '' => nil,
+ 'true' => true,
+ 'false' => false,
+ 'blank' => :blank?,
+ 'empty' => :empty?
+ }
+
# Look up variable, either resolve directly after considering the name. We can directly handle
# Strings, digits, floats and booleans (true,false).
# If no match is made we lookup the variable in the current scope and
# later move up to the parent blocks to see if we can resolve the variable somewhere up the tree.
# Some special keywords return symbols. Those symbols are to be called on the rhs object in expressions
#
# Example:
# products == empty #=> products.empty?
def resolve(key)
- case key
- when nil, 'nil', 'null', ''
- nil
- when 'true'
- true
- when 'false'
- false
- when 'blank'
- :blank?
- when 'empty' # Single quoted strings
- :empty?
- when /^'(.*)'$/ # Double quoted strings
- $1.to_s
- when /^"(.*)"$/ # Integer and floats
- $1.to_s
- when /^(\d+)$/ # Ranges
- $1.to_i
- when /^\((\S+)\.\.(\S+)\)$/ # Floats
- (resolve($1).to_i..resolve($2).to_i)
- when /^(\d[\d\.]+)$/
- $1.to_f
+ if LITERALS.key?(key)
+ LITERALS[key]
else
- variable(key)
+ case key
+ when /^'(.*)'$/ # Single quoted strings
+ $1
+ when /^"(.*)"$/ # Double quoted strings
+ $1
+ when /^(-?\d+)$/ # Integer and floats
+ $1.to_i
+ when /^\((\S+)\.\.(\S+)\)$/ # Ranges
+ (resolve($1).to_i..resolve($2).to_i)
+ when /^(-?\d[\d\.]+)$/ # Floats
+ $1.to_f
+ else
+ variable(key)
+ end
end
end
# Fetches an object starting at the local scope and then moving up the hierachy
def find_variable(key)