Path: csiph.com!x330-a1.tempe.blueboxinc.net!usenet.pasdenom.info!aioe.org!feeder.news-service.com!news2.euro.net!feeds.phibee-telecom.net!talisker.lacave.net!lacave.net!not-for-mail From: 7stud -- Newsgroups: comp.lang.ruby Subject: Re: What do you do when you need to attach data to an object instance? Date: Thu, 14 Apr 2011 19:01:01 -0500 Organization: Service de news de lacave.net Lines: 66 Message-ID: <8de4b1a0d2a83352a656f12fff91d581@ruby-forum.com> References: NNTP-Posting-Host: bristol.highgroove.com Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit X-Trace: talisker.lacave.net 1302825696 7474 65.111.164.187 (15 Apr 2011 00:01:36 GMT) X-Complaints-To: abuse@lacave.net NNTP-Posting-Date: Fri, 15 Apr 2011 00:01:36 +0000 (UTC) In-Reply-To: X-Received-From: This message has been automatically forwarded from the ruby-talk mailing list by a gateway at comp.lang.ruby. If it is SPAM, it did not originate at comp.lang.ruby. Please report the original sender, and not us. Thanks! For more details about this gateway, please visit: http://blog.grayproductions.net/categories/the_gateway X-Mail-Count: 381583 X-Ml-Name: ruby-talk X-Rubymirror: Yes X-Ruby-Talk: <8de4b1a0d2a83352a656f12fff91d581@ruby-forum.com> Xref: x330-a1.tempe.blueboxinc.net comp.lang.ruby:2894 Aaron D. Gifford wrote in post #992841: > What do you do when you see a need to be able to attach some data to > an object instance for later use somewhere else in a body of code? > Lately I've resorted to this: > > ## Generic utility to allow one to attach data with a getter/setter to > ## any instance of any object so long as there isn't a method name > ## collision: > def attach_data(obj, name, data) > getter = name.to_sym > setter = (name.to_s + '=').to_sym > raise "method name collision for #{obj.class} instance" if > obj.respond_to?(getter) || obj.respond_to?(setter) > ## The 'value' local variable will remain in existence in the lambda > closures below: > value = data > meta = class << obj ; self ; end > meta.send(:define_method, getter, lambda { value }) > meta.send(:define_method, setter, lambda {|val| value = val }) > 1) Note that you don't need to use send() there -- but maybe that's your preferred closure? Once you have the singleton class, you can define methods on it like this: def attach_data(obj, name, data) getter = name.to_sym setter = (name.to_s + '=').to_sym raise "method name collision for #{obj.class} instance" if obj.respond_to?(getter) || obj.respond_to?(setter) #value = data singleton = class <