在Ruby中选择变量赋值后执行方法

时间:2012-01-09 07:09:55

标签: ruby variable-assignment dry

我正在尝试干掉一些代码,我觉得Ruby的变量赋值必须提供一种简化这种方法的方法。我有一个定义了许多不同实例变量的类。其中一些是隐藏的(或只读的),但许多是公开的,具有读/写访问权限。

对于所有具有公共写访问权限的变量,我想在每次赋值后执行某个方法。我知道,一般来说,我可以这样做:

def foo=(new_foo)
    @foo = new_foo
    post_process(@foo)
end

def bar=(new_bar)
    @bar = new_bar
    post_process(@foo)
end

然而,似乎应该有一个很好的方法来干这个,因为我在每次分配后基本上做同样的事情(即,运行相同的方法,并将新分配的变量作为参数传递给那个方法)。由于我有很多这样的变量,所以有一个通用的解决方案会很棒。

1 个答案:

答案 0 :(得分:2)

更简单的解决方案

如果您批量分配这些变量,您可以执行以下操作:

kv_pairs = {:foo => new_foo_value,
  :bar => new_bar_value}

kv_pairs.each do |k, v|
  self.send(k.to_s + '=', v)
  post_process(v)
end

元编程

这是一些红宝石魔法: - )

module PostProcessAssignments
  def hooked_accessor( *symbols )
    symbols.each { | symbol |
      class_eval( "def #{symbol}() @#{symbol}; end" )
      class_eval( "def #{symbol}=(val) @#{symbol} = val; post_process('#{symbol}', val); end" )
    }
  end
end

class MyClass
  extend PostProcessAssignments

  hooked_accessor :foo

  def post_process prop, val
    puts "#{prop} was set to #{val}"
  end


end

mc = MyClass.new
mc.foo = 4
puts mc.foo

输出:

foo was set to 4
4