module StateMachine::EvalHelpers
Provides a set of helper methods for evaluating methods within the context of an object.
Public Instance Methods
evaluate_method(object, method, *args, &block)
click to toggle source
Evaluates one of several different types of methods within the context of the given object. Methods can be one of the following types:
-
Symbol
-
Method / Proc
-
String
Examples¶ ↑
Below are examples of the various ways that a method can be evaluated on an object:
class Person def initialize(name) @name = name end def name @name end end class PersonCallback def self.run(person) person.name end end person = Person.new('John Smith') evaluate_method(person, :name) # => "John Smith" evaluate_method(person, PersonCallback.method(:run)) # => "John Smith" evaluate_method(person, Proc.new {|person| person.name}) # => "John Smith" evaluate_method(person, lambda {|person| person.name}) # => "John Smith" evaluate_method(person, '@name') # => "John Smith"
Additional arguments¶ ↑
Additional arguments can be passed to the methods being evaluated. If the method defines additional arguments other than the object context, then all arguments are required.
For example,
person = Person.new('John Smith') evaluate_method(person, lambda {|person| person.name}, 21) # => "John Smith" evaluate_method(person, lambda {|person, age| "#{person.name} is #{age}"}, 21) # => "John Smith is 21" evaluate_method(person, lambda {|person, age| "#{person.name} is #{age}"}, 21, 'male') # => ArgumentError: wrong number of arguments (3 for 2)
# File lib/state_machine/eval_helpers.rb 53 def evaluate_method(object, method, *args, &block) 54 case method 55 when Symbol 56 klass = (class << object; self; end) 57 args = [] if (klass.method_defined?(method) || klass.private_method_defined?(method)) && object.method(method).arity == 0 58 object.send(method, *args, &block) 59 when Proc, Method 60 args.unshift(object) 61 arity = method.arity 62 63 # Procs don't support blocks in < Ruby 1.9, so it's tacked on as an 64 # argument for consistency across versions of Ruby 65 if block_given? && Proc === method && arity != 0 66 if [1, 2].include?(arity) 67 # Force the block to be either the only argument or the 2nd one 68 # after the object (may mean additional arguments get discarded) 69 args = args[0, arity - 1] + [block] 70 else 71 # Tack the block to the end of the args 72 args << block 73 end 74 else 75 # These method types are only called with 0, 1, or n arguments 76 args = args[0, arity] if [0, 1].include?(arity) 77 end 78 79 method.is_a?(Proc) ? method.call(*args) : method.call(*args, &block) 80 when String 81 eval(method, object.instance_eval {binding}, &block) 82 else 83 raise ArgumentError, 'Methods must be a symbol denoting the method to call, a block to be invoked, or a string to be evaluated' 84 end 85 end