在 ruby 方法上定义自定义回调

Define custom callbacks on ruby method

我有许多服务 classes,其中 call 方法的参数有所不同。

我想在每个 call 方法的末尾调用一个函数 notify。我不想修改那些服务 classes 但我愿意修改基础 class。

我正在玩ActiveSupport::Callbacks,但它不能达到不修改服务的目的class。

require 'active_support'
class Base
  include ActiveSupport::Callbacks
  define_callbacks :notifier

  set_callback :notifier, :after do |object|
    notify()
  end

  def notify
    puts "notified successfully"
  end
end

class NewPost < Base
  def call
    puts "Creating new post on WordPress"
    # run_callbacks :notifier do
    #   puts "notifying....."
    # end
  end
end

class EditPost < Base
  def call
    puts "Editing the post on WordPress"
    # run_callbacks :notifier do
    #   puts "notified successfully"
    # end
  end
end

person = NewPost.new
person.call

问题 为了运行回调,我需要取消注释代码。但是在这里你可以看到我需要修改现有的 classes 来添加 run_callbacks 块。但这不是我想要的。我可以轻松地调用 notify 方法而不用增加这种复杂性。

任何人都可以建议我如何找到解决方案 ruby 的方法吗?

我会这样做:

require 'active_support'
class Base
  include ActiveSupport::Callbacks
  define_callbacks :notifier

  set_callback :notifier, :after do |object|
    notify()
  end

  def notify
    puts "notified successfully"
  end

  def call
    run_callbacks :notifier do
      do_call
    end
  end

  def do_call
    raise 'this should be implemented in children classes'
  end
end

class NewPost < Base
  def do_call
    puts "Creating new post on WordPress"
  end
end

person = NewPost.new
person.call

另一种没有 ActiveSupport 的解决方案:

module Notifier
  def call
    super
    puts "notified successfully"
  end
end


class NewPost
  prepend Notifier

  def call
    puts "Creating new post on WordPress"
  end
end

NewPost.new.call

您应该检查您的 ruby 版本 prepend 是 "new" 方法 (2.0)

一般在继承类中设置回调。不确定你想从你的例子中实现什么,但从你最初的描述来看它应该是这样的:

require 'active_support'

class Base
  include ActiveSupport::Callbacks
  define_callbacks :call

  def call
    run_callbacks(:call) { puts "something is happening..." }
  end
end

class Post < Base
  set_callback :notify, :after, :call

  private

  def notify
    puts "new post!"
  end
end

post = Post.new
post.call