--- 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