You want to define a dynamic method for the singleton class of the class you are extending. You can get an expression for a singleton class of a class as follows: class << self; self end class << self; self end . To open a class of a class, you can use class_eval . Combining all this, you can write:
module Identification def add_identifier(identifier) (class << self; self end).class_eval do define_method(identifier) do |*args| value = args.first if value instance_variable_set("@#{identifier}", value) else instance_variable_get("@#{identifier}") end end end end end class A extend Identification add_identifier :tag end
If you are using the latest versions of Ruby, this approach can be replaced with Module # define_singleton_method :
module Identification def add_identifier(identifier) define_singleton_method(identifier) do |value = nil| if value instance_variable_set("@#{identifier}", value) else instance_variable_get("@#{identifier}") end end end end
I don't think you want to use self.class.send(:define_method) as shown in another answer here; this has an unintended side effect of adding a dynamic method to all child classes of self.class , which in case of A in my example is Class .
source share