module UltraMarathon::Contexticution
Public Instance Methods
contexticute(object, args=[], context=self)
click to toggle source
@param object [Symbol, String
, Proc] a symbol representing a method name,
a string to be eval'd, or a proc to be called in the given context
@param args [Array] arguments to be passed to object
@param context [Object] the context in which to evaluate object
. Defaults
to self
# File lib/ultra_marathon/contexticution.rb, line 11 def contexticute(object, args=[], context=self) bound_proc = bind_to_context(object, context) evaluate_block_with_arguments(bound_proc, args) end
Private Instance Methods
bind_to_context(object, context)
click to toggle source
Binds a proc to the given context. If a symbol is passed in, retrieves the bound method. If it is a string, generates a lambda wrapping it.
# File lib/ultra_marathon/contexticution.rb, line 20 def bind_to_context(object, context) if object.is_a?(Symbol) context.method(object) elsif object.respond_to?(:call) object.bind(context) elsif object.is_a?(String) eval("lambda { #{object} }").bind(context) else raise ArgumentError.new("Cannot bind #{callback.class} to #{context}. Expected Symbol, String, or object responding to #call.") end end
evaluate_block_with_arguments(block, args)
click to toggle source
Applies a block in context with the correct number of arguments. If there are more arguments than the arity, takes the first n arguments where (n) is the arity of the block. If there are the same number of arguments, splats them into the block. Otherwise throws an argument error.
# File lib/ultra_marathon/contexticution.rb, line 37 def evaluate_block_with_arguments(block, args) # If block.arity < 0, when a block takes a variable number of args, # the one's complement (-n-1) is the number of required arguments required_arguments = block.arity < 0 ? ~block.arity : block.arity if args.length >= required_arguments if block.arity < 0 instance_exec(*args, &block) else instance_exec(*args.first(block.arity), &block) end else raise ArgumentError.new("wrong number of arguments (#{args.size} for #{required_arguments})") end end