How can I get a reference to a method?

You want Object#method:

---------------------------------------------------------- Object#method
     obj.method(sym)    => method
------------------------------------------------------------------------
     Looks up the named method as a receiver in obj, returning a Method 
     object (or raising NameError). The Method object acts as a closure 
     in obj's object instance, so instance variables and the value of 
     self remain available.

        class Demo
          def initialize(n)
            @iv = n
          end
          def hello()
            "Hello, @iv = #{@iv}"
          end
        end

        k = Demo.new(99)
        m = k.method(:hello)
        m.call   #=> "Hello, @iv = 99"

        l = Demo.new('Fred')
        m = l.method("hello")
        m.call   #=> "Hello, @iv = Fred"

Now your code becomes:

private
def setup_map
  @map = {
    'a' => method(:a),
    'b' => method(:b),
    'c' => method(:c)
  }
  # or, more succinctly
  # @map = Hash.new { |_map,name| _map[name] = method(name.to_sym) }
end

public
def call(arg)
  @map["a"][arg] if arg > 10
  @map["b"][arg] if arg > 20
  @map["c"][arg] if arg > 30
end

Leave a Comment