2009-09-14 88 views
16

我想在Ruby中的数组中存储几种不同的方法。假设我要存放type方法两次:ruby​​中的方法指针

[type, type] 

type两个条目不存储在阵列中;它执行两次type,并将结果存储在数组中。我如何明确地引用方法对象本身?

(这只是一个简单的我真正想要的版本。)

编辑:在第二个想法,它困扰我下面提出的解决方案通过将方法的名称避免了这个问题。你如何传递方法对象本身?例如,如果将[:type,:type]传递给具有替代类型分辨率的方法,该怎么办?你怎么能通过类型方法对象本身?

回答

31

如果你想存储的方法,而不是调用你发送调用方法或只是消息的结果它,你需要在拥有的对象上使用method方法。因此,例如

"hello".method(:+) 

将返回对象“你好”的方法+,所以如果你的说法“世界”称呼它,你会得到的“Hello World”。

helloplus = "hello".method(:+) 
helloplus.call " world" # => "hello world" 
+0

[方法(:类型),方法(:类型)] – jrhicks 2009-09-14 02:58:44

+0

@jrhicks:只有当方法属于自己。 – Chuck 2009-09-14 03:06:17

+0

首先SO红宝石徽章 - 恭喜! – 2009-09-14 08:13:48

1
[:type, :type].collect { |method_name| self.send(method_name) } 

另外,如果该方法是一个对象的一部分:

method = obj.method(:type) 
values = [method.call, method.call] 
+0

这似乎不适用于我 - 它只是导致'[Object,Object]'。 – Peter 2009-09-14 01:50:07

+0

答案的第一部分基本上是从irb复制粘贴的,所以我认为简化你的情况正在搞砸它。 – 2009-09-14 01:52:14

+0

看起来很对我。 Object的类型是Object ...您可能需要'self.send(method_name)',因此它将方法应用于对象而不是全局Object对象。 – 2009-09-14 01:53:36

11

如果你在考虑在Ruby中做方法引用,那么你做错了。

Ruby中有一种内置方法,名为method。它将返回该方法的proc版本。不过,这不是对原始方法的参考。每拨打method都会创建一个新的proc。例如,更改方法不会影响proc。

def my_method 
    puts "foo" 
end 

copy = method(:my_method) 

# Redefining 
def my_method 
    puts "bar" 
end 

copy.call 
# => foo 

当你想存储代码片段,并且不想使用常规方法时,请使用procs。

stack = [proc { do_this }, proc { do_that }] 
stack.each {|s| s.call } 
+0

正如我在评论中对我的回答所说的,这正是它应该如何工作的。你不“改变方法”,你替换方法。很显然,对旧方法的引用仍然会引用旧方法,就像给旧实例变量引用一样,即使给实例变量一个新值,它仍然会引用旧方法。如果您想要动态调度而不是存储特定的方法,则需要改为发送消息。 – Chuck 2009-09-14 15:25:30