From: Phrogz Date: 2006-10-17T13:30:11+09:00 Subject: Re: dynamically assigning instance variables (redux) Phrogz wrote: > class Foo > def initialize( hash={} ) > hash.each{ |key,value| > var_name = "@#{key}" > instance_variable_set( var_name, value ) > singleton_class = class << self; self; end > singleton_class.class_eval{ > define_method( key ){ > instance_variable_get( var_name ) > } > define_method( "#{key}=" ){ |new_value| > instance_variable_set( var_name, new_value ) > } > } > } > end > end Note that the above defines distinct readers/writers for each instance: f1 = Foo.new :name=>'whee', :age=>12 f2 = Foo.new :chicken=>'gorkbo' p f1, f2 #=> # #=> # p f1.name #=> "whee" p f2.name #=> NoMethodError: undefined method `name' for # #=> at top level in tmp.rb at line 26 You can also open up the main class (instead of the singleton class) to define the methods shared by all instances, or store the hash as an instance variable and use method_missing to dynamically catch and report values as appropriate. Here's an example of that for Hash objects in general: class Hash # Causes *all* Hash objects to behave similar to Object literals in JS, # with their keys accessible via dot notation. # foo = { 'name'=>'Gavin', 'age'=>33 } # foo.weight = 180 # p foo.name, foo.weight # #=> "Gavin" # #=> 180 # # p foo.zzzz # #=> NoMethodError: undefined method `zzzz' for # #=> {"name"=>"Gavin", "weight"=>180, "age"=>33}:Hash alias_method :__mMm__, :method_missing def method_missing(meth,*args) if /=$/ =~ (meth=meth.id2name) # Name ends with an equals sign; shove value to the hash self[ meth[0...-1] ] = (args.length<2 ? args[0] : args) else # Retrieve the value if self.key?( meth ) self[ meth ] else # Let the real method_missing handle/pass on up __mMm__( meth.intern, *args ) end end end end TIMTOWTDI.