This post originated from an RSS feed registered with Ruby Buzz
by Red Handed.
Original Post: Eval-less Metaprogramming
Feed Title: RedHanded
Feed URL: http://redhanded.hobix.com/index.xml
Feed Description: sneaking Ruby through the system
I often find myself resorting to eval when writing class methods for metaprogramming, simply because define_method hasn’t penetrated my brain basket yet. No more!
Here goes Florian GroBB changing Ruby as I know it—yet again—with his implementation of an eval-less has_many class method:
class Meta
def self.has_many( sym )
ivar = :"@#{ sym }"
define_method( sym.to_sym ) do
new_value = instance_variable_get( ivar ) || []
instance_variable_set( ivar, new_value )
new_value
end
end
end
Even though has_many is a sorta poor name (we’re not talking about databases here), this method acts like an attr method, but the attribute is always an Array.
class Person < Meta
attr_accessor :name
has_many :friends
def initialize( name ); @name = name; end
end
>> fred = Person.new( "Fred" )
>> joe = Person.new( "Joe" )
>> teagle = Person.new( "T. Eagle" )
>> teagle.friends << fred
>> teagle.friends << joe
=> [#, #]