首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何在Ruby中实现“回调”?

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

Stack Overflow用户
提问于 2009-11-05 09:52:39
回答 5查看 58.1K关注 0票数 77

我不确定Ruby中C风格回调的最好习惯用法是什么--或者是否有更好的东西(不太像C语言)。在C语言中,我会这样做:

代码语言:javascript
复制
void DoStuff( int parameter, CallbackPtr callback )
{
  // Do stuff
  ...
  // Notify we're done
  callback( status_code )
}

什么是好的Ruby等价物?本质上,当"DoStuff“中满足特定条件时,我希望调用传入的类方法。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2009-11-05 12:06:18

ruby的等价物不是惯用的,应该是:

代码语言:javascript
复制
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

惯用的方法是传递一个块,而不是对方法的引用。与独立方法相比,块的一个优点是上下文--块是一个closure,因此它可以引用声明它的作用域中的变量。这减少了do_stuff需要传递给回调的参数数量。例如:

代码语言:javascript
复制
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
票数 98
EN

Stack Overflow用户

发布于 2018-08-16 18:00:23

如果您愿意使用ActiveSupport (来自Rails),那么您就有了一个简单的实现

代码语言:javascript
复制
class ObjectWithCallbackHooks
  include ActiveSupport::Callbacks
  define_callbacks :initialize # Your object supprots an :initialize callback chain

  include ObjectWithCallbackHooks::Plugin 

  def initialize(*)
    run_callbacks(:initialize) do # run `before` callbacks for :initialize
      puts "- initializing" # then run the content of the block
    end # then after_callbacks are ran
  end
end

module ObjectWithCallbackHooks::Plugin
  include ActiveSupport::Concern

  included do 
    # This plugin injects an "after_initialize" callback 
    set_callback :initialize, :after, :initialize_some_plugin
  end
end
票数 1
EN

Stack Overflow用户

发布于 2021-09-29 12:58:33

我知道这是一个古老的帖子,但我在尝试解决类似的问题时发现了它。

这是一个非常优雅的解决方案,最重要的是,它可以在有或没有回调的情况下工作。

假设我们有Arithmetic类,它实现了对它们的基本操作- additionsubtraction

代码语言:javascript
复制
class Arithmetic
  def addition(a, b)
    a + b
  end

  def subtraction(a, b)
    a - b
  end
end

我们希望为每个操作添加一个回调,该回调将对输入数据和结果执行一些操作。

在下面的示例中,我们将实现接受Ruby块的after_operation方法,该块将在操作后执行。

代码语言:javascript
复制
class Arithmetic
  def after_operation(&block)
    @after_operation_callback = block
  end

  def addition(a, b)
    do_operation('+', a, b)
  end

  def subtraction(a, b)
    do_operation('-', a, b)
  end

  private

  def do_operation(sign, a, b)
    result =
      case sign
      when '+'
        a + b
      when '-'
        a - b
      end

    if callback = @after_operation_callback
      callback.call(sign, a, b, result)
    end

    result
  end
end

使用with callback:

代码语言:javascript
复制
callback = -> (sign, a, b, result) do
  puts "#{a} #{sign} #{b} = #{result}"
end

arithmetic = Arithmetic.new
arithmetic.after_operation(&callback)

puts arithmetic.addition(1, 2)
puts arithmetic.subtraction(3, 1)

输出:

代码语言:javascript
复制
1 + 2 = 3
3
3 - 1 = 2
2
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1677861

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档