- Check arity of proc before calling, to prevent error when using ruby 1.9.1+

Code beautifer
  - context.rb
This commit is contained in:
DBA
2010-08-23 01:30:03 +08:00
committed by Tobias Lütke
parent c72c84ea9b
commit 8304a046c9
+29 -34
View File
@@ -28,8 +28,9 @@ module Liquid
@strainer ||= Strainer.create(self) @strainer ||= Strainer.create(self)
end end
# adds filters to this context. # Adds filters to this context.
# this does not register the filters with the main Template object. see <tt>Template.register_filter</tt> #
# Note that this does not register the filters with the main Template object. see <tt>Template.register_filter</tt>
# for that # for that
def add_filters(filters) def add_filters(filters)
filters = [filters].flatten.compact filters = [filters].flatten.compact
@@ -52,7 +53,6 @@ module Liquid
end end
end end
def invoke(method, *args) def invoke(method, *args)
if strainer.respond_to?(method) if strainer.respond_to?(method)
strainer.__send__(method, *args) strainer.__send__(method, *args)
@@ -61,40 +61,41 @@ module Liquid
end end
end end
# push new local scope on the stack. use <tt>Context#stack</tt> instead # Push new local scope on the stack. use <tt>Context#stack</tt> instead
def push(new_scope={}) def push(new_scope={})
raise StackLevelError, "Nesting too deep" if @scopes.length > 100 raise StackLevelError, "Nesting too deep" if @scopes.length > 100
@scopes.unshift(new_scope) @scopes.unshift(new_scope)
end end
# merge a hash of variables in the current local scope # Merge a hash of variables in the current local scope
def merge(new_scopes) def merge(new_scopes)
@scopes[0].merge!(new_scopes) @scopes[0].merge!(new_scopes)
end end
# pop from the stack. use <tt>Context#stack</tt> instead # Pop from the stack. use <tt>Context#stack</tt> instead
def pop def pop
raise ContextError if @scopes.size == 1 raise ContextError if @scopes.size == 1
@scopes.shift @scopes.shift
end end
# pushes a new local scope on the stack, pops it at the end of the block # Pushes a new local scope on the stack, pops it at the end of the block
# #
# Example: # Example:
#
# context.stack do # context.stack do
# context['var'] = 'hi' # context['var'] = 'hi'
# end # end
# context['var] #=> nil
# #
# context['var] #=> nil
def stack(new_scope={},&block) def stack(new_scope={},&block)
result = nil result = nil
push(new_scope) push(new_scope)
begin begin
result = yield result = yield
ensure ensure
pop pop
end end
result result
end end
@@ -116,16 +117,14 @@ module Liquid
end end
private private
# Look up variable, either resolve directly after considering the name. We can directly handle # 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 # 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. # 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 # Some special keywords return symbols. Those symbols are to be called on the rhs object in expressions
# #
# Example: # Example:
#
# products == empty #=> products.empty? # products == empty #=> products.empty?
#
def resolve(key) def resolve(key)
case key case key
when nil, 'nil', 'null', '' when nil, 'nil', 'null', ''
@@ -136,21 +135,16 @@ module Liquid
false false
when 'blank' when 'blank'
:blank? :blank?
when 'empty' when 'empty' # Single quoted strings
:empty? :empty?
# Single quoted strings when /^'(.*)'$/ # Double quoted strings
when /^'(.*)'$/
$1.to_s $1.to_s
# Double quoted strings when /^"(.*)"$/ # Integer and floats
when /^"(.*)"$/
$1.to_s $1.to_s
# Integer and floats when /^(\d+)$/ # Ranges
when /^(\d+)$/
$1.to_i $1.to_i
# Ranges when /^\((\S+)\.\.(\S+)\)$/ # Floats
when /^\((\S+)\.\.(\S+)\)$/
(resolve($1).to_i..resolve($2).to_i) (resolve($1).to_i..resolve($2).to_i)
# Floats
when /^(\d[\d\.]+)$/ when /^(\d[\d\.]+)$/
$1.to_f $1.to_f
else else
@@ -158,10 +152,10 @@ module Liquid
end end
end end
# fetches an object starting at the local scope and then moving up # Fetches an object starting at the local scope and then moving up the hierachy
# the hierachy
def find_variable(key) def find_variable(key)
scope = @scopes.find { |s| s.has_key?(key) } scope = @scopes.find { |s| s.has_key?(key) }
if scope.nil? if scope.nil?
@environments.each do |e| @environments.each do |e|
if variable = lookup_and_evaluate(e, key) if variable = lookup_and_evaluate(e, key)
@@ -170,27 +164,28 @@ module Liquid
end end
end end
end end
scope ||= @environments.last || @scopes.last scope ||= @environments.last || @scopes.last
variable ||= lookup_and_evaluate(scope, key) variable ||= lookup_and_evaluate(scope, key)
variable = variable.to_liquid variable = variable.to_liquid
variable.context = self if variable.respond_to?(:context=) variable.context = self if variable.respond_to?(:context=)
return variable return variable
end end
# resolves namespaced queries gracefully. # Resolves namespaced queries gracefully.
# #
# Example # Example
#
# @context['hash'] = {"name" => 'tobi'} # @context['hash'] = {"name" => 'tobi'}
# assert_equal 'tobi', @context['hash.name'] # assert_equal 'tobi', @context['hash.name']
# assert_equal 'tobi', @context['hash["name"]'] # assert_equal 'tobi', @context['hash["name"]']
#
def variable(markup) def variable(markup)
parts = markup.scan(VariableParser) parts = markup.scan(VariableParser)
square_bracketed = /^\[(.*)\]$/ square_bracketed = /^\[(.*)\]$/
first_part = parts.shift first_part = parts.shift
if first_part =~ square_bracketed if first_part =~ square_bracketed
first_part = resolve($1) first_part = resolve($1)
end end
@@ -229,15 +224,15 @@ module Liquid
end end
object object
end end # variable
def lookup_and_evaluate(obj, key) def lookup_and_evaluate(obj, key)
if (value = obj[key]).is_a?(Proc) && obj.respond_to?(:[]=) if (value = obj[key]).is_a?(Proc) && obj.respond_to?(:[]=)
obj[key] = value.call(self) obj[key] = (value.arity == 0) ? value.call : value.call(self)
else else
value value
end end
end end # lookup_and_evaluate
def squash_instance_assigns_with_environments def squash_instance_assigns_with_environments
@scopes.last.each_key do |k| @scopes.last.each_key do |k|
@@ -248,7 +243,7 @@ module Liquid
end end
end end
end end
end end # squash_instance_assigns_with_environments
end # Context
end end # Liquid
end