--- Robert Klemme <bob.news / gmx.net> wrote: > > define_method, instance_eval, class_eval, module_eval, and > > maybe others seem to have this special ability - rebind the > > meaning of self (but not locals) for a Proc. This brings > us > > back to the topic I talked about earlier - unbind/rebind > procs. > > It would be nice if we could do the same thing to a Proc > that > > these methods can do internally: > > > > aProc.rebind_self(obj) -> aNewProc # rebind what self is > > > > With this, "obj.instance_eval(&proc)" would be equivalent > to > > "proc.rebind_self(obj).call". > > Why do you want rebind if the other approach is much simpler? > > #instance_eval *always* rebinds self (and only self). because you can get a handle on that rebound Proc. You might want to pass it around or whatever. > > Other useful rebindings may be: > > > > aProc.rebind_locals(binding) -> aNewProc > > aProc.rebind_all(binding) -> aNewProc > > # replace local variables with their current values > > aProc.unbind_locals -> aNewProc > > When do you think will unbind_locals be useful? As a replacement for many string evals - which are ugly, inefficient, and possibly dangerous. Many (most?) times that you need to eval a string it is because you need to pull in some local variables to help define the string to be evaled. Here is the first example of a string eval in the 1.8 library I found: for element in %w[ HTML HEAD BODY P PLAINTEXT DT DD LI OPTION tr th td ] methods += <<-BEGIN + nO_element_def(element) + <<-END def #{element.downcase}(attributes = {}) BEGIN end END end eval(methods) This could be replaced by: for element in %w[ HTML HEAD BODY P PLAINTEXT DT DD LI OPTION tr th td ] define_method(element.downcase.to_sym , proc { |attributes={}| nO_element_def(element) }.unbind_locals # replace element with constant ) end Much cleaner, huh? > A proc > typically needs some > of the variables bound. As for the rebindings, I would > prefer a general > mechanism to transfer state from one binding to another. > Then one could > implement all your rebind* methods in terms of that general > mechanism plus > do more. Alternatively one could think about conversion > methods Binding <-> > Hash. Transferring locals might be pretty easy, but transferring the meaning of self would be more difficult, I think. At least without making a new Binding (and then you'd still need a way to rebind it to the original proc). > > BTW, I don't see the value that class_eval and module_eval > > provide over instance_eval. classes and modules can be > treated > > like instances just like any other object. > > class_eval and instance_eval are not equivalent: > > >> class Foo;end > => nil > >> Foo.class_eval do > ?> def bar() "bar" end > >> end > => nil > >> Foo.new.bar > => "bar" > >> Foo.instance_eval do > ?> def bax() "bax" end > >> end > => nil > >> Foo.new.bax > NoMethodError: undefined method `bax' for #<Foo:0x10179ee0> > from (irb):12 Interesting. I assumed that since class_eval/instance_eval/module_eval all returned the same "self" that they did the same thing. The only difference I see is in "def <method> ...". With class_eval, it defines instance methods and with instance_eval, it defines class methods. That's kind of strange. Some kind of magic is going on here other than the changing of self. I was hoping that instance_eval could be used to define class methods using #define_method, but #define_method does the same with both - defines instance methods. Anybody know of an equivalent to #define_method for making class methods? I couldn't figure out any way to define a class method from a proc - just out of curiosity. __________________________________ Do you Yahoo!? Yahoo! Mail - Helps protect you from nasty viruses. http://promotions.yahoo.com/new_mail