пятница, 27 февраля 2015 г.

Ruby attr_accessor: добавляем callback на изменение аттрибута

Оказывается, в Ruby очень просто сделать так чтобы при изменении аттрибута вызывался произвольный code block.

Сначала определить новый  attr_accessor с такой фичей:
class Class
  def attr_accessor_with_onchange_callback(*args, &block)
    raise 'Callback block is required' unless block
    args.each do |arg|
      attr_name = arg.to_s
      define_method(attr_name) do
         self.instance_variable_get("@#{attr_name}")
      end
      define_method("#{attr_name}=") do |argument|
        if argument != self.instance_variable_get("@#{attr_name}")
          self.instance_variable_set("@#{attr_name}", argument)
          self.instance_exec(attr_name, argument, &block)
        end
      end   
    end
  end
end

Использование:
class MyClass
  attr_accessor_with_onchange_callback :my_var do |attr_name, value|
    puts "#{attr_name} changed value to #{value}"
  end
end
Теперь при всяком изменении my_var будет вызываться блок:
m = MyClass.new
m.my_var = 1
m.my_var = 100500

=> my_var changed value to 1
=> my_var changed value to 100500

Комментариев нет:

Отправить комментарий