I am trying to add a method to Observable, so that for a class that includes it, it can call the method observe_attribute :attribute
that would generate a method attribute=
with the logic to check to see if the value has changed:
module Observable
def observe_attribute(attribute)
raise NameError, "#{self.class} does not contain #{attribute}" unless instance_variables.include? "@#{attribute}"
eval %" def #{attribute}=(new_value)
unless @#{attribute} == new_value
changed
notify_observers
puts 'ok'
end
end
";
end
end
However, for the following class, the last call to observe_attribute :att
results in a NoMethodError, while the commented one does not:
class Test
include Observable
def initialize
@att = 3
#observe_attribute :att
end
observe_attribute :att
end
What would I need to do in order for the last call to observe_attribute
to work correctly?
When you include a module, the methods contained in it are loaded into the "instance" level of methods.
If you want to include methods from a module into the Class scope, you have to extend the module.
Or if you need both, but you want to package it as a single "include", you can extend the "included" method of the module you're extending and do a bit of magic with it by extending and including 2 modules from there.
Now you can call ...
And then the result would be ...