Когда вы включаете модуль, методы, содержащиеся в нем, загружаются на уровень «экземпляра» методов.
Если вы хотите включить методы из модуля в область действия класса, вы должны расширить модуль.
Или, если вам нужно и то и другое, но вы хотите упаковать его как единое «включение», вы можете расширить метод «включенного» модуля, который вы расширяете, и немного поработать с ним, расширив и включив 2 модули оттуда.
module Observable
def self.included(other)
other.send(:include, InstanceMethods)
other.send(:extend, ClassMethods)
end
module InstanceMethods
def some_helper
puts "called some_helper"
end
def other_helper
puts "called other_helper"
end
end
module ClassMethods
def observe_attribute(name)
# do something useful, maybe in your case define the method
define_method("#{name}=") do |val|
puts "called #{name}= #{val}"
# bla bla
some_helper
other_helper
# end
puts "done"
end
end
end
end
class Foo
include Observable
observe_attribute :foo
end
Теперь вы можете звонить ...
o = Foo.new
o.foo = :bar
И тогда результат будет ...
called foo= bar
called some_helper
called other_helper
done