Ruby:在'attr'对象上有回调

时间:2010-05-25 14:49:23

标签: ruby callback

基本上我想知道如何在ruby中的对象上放置回调,这样当一个对象被改变时,我可以自动触发其他更改:

(编辑:我在自己的例子中感到困惑!不是一个好兆头...因为@proxy是一个URI对象,它有自己的方法,通过使用它自己的方法来改变URI对象不会调用我自己的{{1方法并更新@http对象)

proxy=

2 个答案:

答案 0 :(得分:0)

您的第m.proxy = nil行会引发NoMethodError例外,因为nil没有回复empty?。因此,@http设置为Net::HTTP,与救援条款一样。

这与回调/设置器无关。您应修改代码以执行所需操作(例如,如果使用activesupport,则调用string_proxy.blank?。)

答案 1 :(得分:0)

我设法为自己找到了这个!

# Unobtrusive modifications to the Class class.
class Class
  # Pass a block to attr_reader and the block will be evaluated in the context of the class instance before
  # the instance variable is returned.
  def attr_reader(*params,&block)
    if block_given?
      params.each do |sym|
        # Create the reader method
        define_method(sym) do
          # Force the block to execute before we…
         self.instance_eval(&block)
          # … return the instance variable
          self.instance_variable_get("@#{sym}")
        end
      end
    else # Keep the original function of attr_reader
      params.each do |sym|
        attr sym
      end
    end
  end
end

如果您在某处添加该代码,它将扩展attr_reader方法,以便您现在执行以下操作:

attr_reader :special_attr { p "This happens before I give you @special_attr" }

它会在它给你@special_attr之前触发阻止。它在实例范围内执行,因此您可以使用它,例如,在从Internet下载属性的类中。如果您定义了get_details这样的方法来执行所有检索并将@details_retrieved设置为true,那么您可以像这样定义attr:

attr_reader :name, :address, :blah { get_details if @details_retrieved.nil? }