instance_exec class_exec module_exec

这几个exec方法只接受代码块。

class Counter
  DEFAULT = 0
  attr_reader :counter

  def initialize(start=DEFAULT)
    @counter = start
  end

  def inc
    @counter += 1
  end
end

现在需要把@counter 设置为默认值

这个方法又注入风险

module Reset
  def self.reset_var(object, name)
    object.instance_eval("@#{name} = DEFAULT")
  end
end

可以使用exec替换

module Reset
  def self.reset_var(object, name)
    object.instance_exec("@#{name}".to_sym) do |var|
      const = self.class.const_get(:DEFAULT)
      instance_variable_set(var, const)
    end
  end
end

Resources

  • Effective Ruby 第31条