中断消息

有两种方法可以中断消息。

  • 使用 method_missing 中断任何未定义的消息。
  • 在链的中间定义一个方法来拦截消息

中断消息后,可以:

  • 回复他们。
  • 将它们发送到其他地方。
  • 修改消息或其结果。

通过 method_missing 中断并回复消息:

class Example
  def foo
    @foo
  end

  def method_missing name, data
    return super unless name.to_s =~ /=$/
    name = name.to_s.sub(/=$/, "")
    instance_variable_set "@#{name}", data
  end
end

e = Example.new

e.foo = :foo
e.foo # => :foo

拦截消息并修改它:

class Example
  def initialize title, body
  end
end

class SubExample < Example
end

现在让我们假设我们的数据是“title:body”,我们必须在调用 Example 之前拆分它们。我们可以在 SubExample 上定义 initialize

class SubExample < Example
  def initialize raw_data
    processed_data = raw_data.split ":"

    super processed_data[0], processed_data[1]
  end
end

拦截消息并将其发送到另一个对象:

class ObscureLogicProcessor
  def process data
    :ok
  end
end

class NormalLogicProcessor
  def process data
    :not_ok
  end
end

class WrapperProcessor < NormalLogicProcessor
  def process data
    return ObscureLogicProcessor.new.process data if data.obscure?

    super
  end
end