为什么使用procs而不是方法?

Nat*_*han 17 ruby proc-object

我是编程的新手,而ruby是我第一次真正的编程.我得到了块,但是procs看起来像一个简单的方法/功能概念 - 为什么要使用它们?为什么不直接使用方法呢?

谢谢你的帮助.

Ser*_*sev 10

Proc是一段可调用的代码.您可以将其存储在变量中,作为参数传递,然后将其视为第一类值.

为什么不直接使用方法呢?

取决于你在这里的"方法"是什么意思.

class Foo
  def bar
    puts "hello"
  end
end

f = Foo.new
Run Code Online (Sandbox Code Playgroud)

在此代码段中,方法的使用bar非常有限.你可以打电话给它,就是这样.但是,如果您想存储对它的引用(要传递到其他地方并调用它),您可以这样做:

f = Foo.new
bar_method = f.method(:bar)
Run Code Online (Sandbox Code Playgroud)

bar_method与lambda非常相似(类似于Proc).bar_method是一流的公民,f.bar不是.

有关更多信息,请阅读@minitech提到的文章.


Dig*_*oss 9

调度表设计模式示例


为什么使用procs而不是方法?

  • 您可能希望根据参数动态定义一个行为.
  • 您可能希望获得方法的句柄,以便可以将其作为数据引用.

常见的设计模式涉及根据运行时值选择要调用的方法或代码块.例如...

case 1
  when 0
    p :a
  when 1
    p :b
  when 2
    p :c
end
Run Code Online (Sandbox Code Playgroud)

当有许多选择器并且没有办法将调度机制递增到一起时,这会变得很笨拙.所以可以这样做:

h = [ proc { p :a }, proc { p :b }, proc { p :c } ]

h[1].call
Run Code Online (Sandbox Code Playgroud)

如果您的键不是一个小整数序列,您也可以使用a HashArray不是a.虽然笨重的案例选择器设计模式经常在所有语言中出现,但很少使用dispatch-of-procs.通常,可以将结果本身存储在Array或中Hash,然后直接将它们编入索引.但对于复杂的事情,调用一个proc允许最大的灵活性.

当你继续使用Ruby时,你会发现这就是Ruby阻塞的原因.块本质上是作为参数传递给另一个方法的方法.这在Ruby和Smalltalk中很容易实现,因此它一直被使用.你可以在C中做同样的事情但是它太尴尬了,所以它只是在C中才能看到代码作者正在失去与复杂性的绝望战斗.