From: James Edward Gray II Date: 2009-09-10T22:28:37+09:00 Subject: Re: defining a singleton method dynamically On Sep 10, 2009, at 7:49 AM, David A. Black wrote: > Hi -- > > On Thu, 10 Sep 2009, Nilesh Trivedi wrote: > >> How do I define a singleton method dynamically? >> >> I have code similar to this: >> >> def foo(obj,label) >> def obj.name; label; end #we want to define a singleton method called >> "name" on obj which returns the value in label >> puts obj.name #this is an example. Actually I have some code here >> which >> expects this singleton method in obj >> end >> >> When I try to run this as foo(Object.new,"xyz"), it throws a >> "NameError: >> undefined local variable or method `label' for #> 0xb7b02018>" whereas >> I want it to print "xyz" to screen. >> >> Of course, line 2 in method foo is not correct. But what is the >> correct way? > > def starts a new local scope, so it won't see label. You need to get > into obj's singleton class, using code blocks rather than class and > def blocks: > > def foo(obj, label) > (class << obj; self; end).class_eval do > define_method("name") { label } > end > end > > You could also do something with eval but I prefer to use the code > block approach rather than the string-eval'ing approach. > > (Still hoping for Object#singleton_class to make the access to the > singleton class a little less awkward :-) I agree, but it's needed a little less in Ruby 1.9 which adds defined_singleton_method(). Thus, in 1.9 your code could be: def foo(obj, label) obj.define_singleton_method(:name) { label } end As a side topic, the fact that this method was added seems to kill the argument about why we can't have singleton_class(). As I understand it, the method we want is never added because we aren't sure if the name is right yet. Seems like we're committed to the name at this point and might as well just get on with defining the methods that help us. James Edward Gray II