如何在Ruby中实现“回调”?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (16)

我不确定C语言call-back在Ruby中是什么或者如果有更好的东西。在C中:

void DoStuff( int parameter, CallbackPtr callback )
{
  // Do stuff
  ...
  // Notify we're done
  callback( status_code )
}
提问于
用户回答回答于

ruby下:

def my_callback(a, b, c, status_code)
  puts "did stuff with #{a}, #{b}, #{c} and got #{status_code}"
end

def do_stuff(a, b, c, callback)
  sum = a + b + c
  callback.call(a, b, c, sum)
end

def main
  a = 1
  b = 2
  c = 3
  do_stuff(a, b, c, method(:my_callback))
end

惯用的方法是传递一个块而不是对方法的引用。块独立于独立方法的一个优点是上下文 - 块是闭包,所以它可以引用声明范围内的变量。这减少了do_stuff需要传递给回调的参数的数量。例如:

def do_stuff(a, b, c, &block)
  sum = a + b + c
  yield sum
end

def main
  a = 1
  b = 2
  c = 3
  do_stuff(a, b, c) { |status_code|
    puts "did stuff with #{a}, #{b}, #{c} and got #{status_code}"
  }
end
用户回答回答于

惯用的方法是使用块:

def x(z)
  yield z   # perhaps used in conjunction with #block_given?
end
x(3) {|y| y*y}  # => 9

或者可能转换为Proc ; 在这里显示:

def x(z, &block)
  callback = block
  callback.call(z)
end

# look familiar?
x(4) {|y| y * y} # => 16

但是,lambda可以轻松使用(不惯用):

def x(z,fn)
  fn.call(z)
end

# just use a lambda (closure)
x(5, lambda {|y| y * y}) # => 25
class A
  def b(z)
    z*z
  end
end

callable = A.new.method(:b)
callable.call(6) # => 36

# and since it's just a value...
def x(z,fn)
  fn.call(z)
end
x(7, callable) # => 49

另外,有时候#send方法是很有用的:

# Using A from previous
def x(z, a):
  a.__send__(:b, z)
end
x(8, A.new) # => 64

扫码关注云+社区