是否有可能在Ruby中获取对象方法的引用(我想知道是否可以在没有procs/lambdas的情况下完成),例如,请考虑以下代码:
class X def initialize @map = {} setup_map end private def setup_map # @map["a"] = get reference to a method # @map["b"] = get reference to b method # @map["c"] = get referebce to c method end public def call(a) @map["a"](a) if a > 10 @map["b"](a) if a > 20 @map["c"](a) if a > 30 end def a(arg) puts "a was called with #{arg}" end def b(arg) puts "b was called with #{arg}" end def c(arg) puts "c was called with #{arg}" end end
有可能做这样的事吗?我想避免procs/lambdas因为我希望能够通过子类化来改变A,B,C的行为.
你想要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"
现在您的代码变为:
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