From: "Jesús Gabriel y Galán" Date: 2011-10-17T16:52:54+09:00 Subject: Re: Setting arbitrary objects On Mon, Oct 17, 2011 at 9:33 AM, Marc Heiler wrote: > Hi. > > For a kind of DSL, I need the following: > >  joker.id = 'koko' >  garfield.colour = 'green' >  superman.speed = 55 > > I think I can solve this with OpenStruct partially. > > BUT, my problem is: > > Is there any way to actually make joker, garfield, superman work as is? > > ALL of these are not known when I run the file! They must be created > dynamically. > > I was thinking I could dynamically create methods like > > def joker() > def garfield() > > etc... > > I can find out the name, like so: > > begin >  joker.id = 'koko' > rescue NameError => error >  object_name = error.name >  method_name = ??? >  exit > end > > > This would give me the name "joker" as result and I could dynamically > create a method called joker, which could return an OpenStruct. > > BUT, how do I obtain the information that we wish to set the .id value > on that object? This could get more complex, when you add more requirements, but with your current description, why do you need to know the method name? If you manage to return an openstruct when the joker part is executed, the call to id would be sent to the openstruct you returned. So I'm not sure why you need to actually know it. The part of creating an openstruct can be handled easily with method_missing. For example: require 'ostruct' def method_missing method, *args, &blk OpenStruct.new end joker.id = 'koko' Now, one problem is that that openstruct object is not referenced by anyone, so what do want to do with that? The second problem I see is that every time you call the joker method a new instance is created so you cannot set several attributes in the same object. One solution would be to create a hash where you store the instances keyed by the method name, but it all depends on what you would like to do with all that later on: require 'ostruct' def method_missing method, *args, &blk @instances ||= {} @instances[method] ||= OpenStruct.new end joker.id = 234234 joker.name = 'koko' superman.color = "red" p @instances {:joker=>#, :superman=>#} Hope this helps, Jesus.