Making a duck

Eric Mahurin ha scritto:

Eric Mahurin wrote:

At Tue, 7 Jun 2005 11:59:47 +0900,
Eric Mahurin wrote in [ruby-talk:144750]:

Is there an advantage to having a separate Behavior class

as

opposed the solution I had: making a singleton Object

directly?

To allow sharing same behavior.

I'm not sure how much application this would have over the
conventional class definition approach.

At first I didn't think this would work because I thought

you

wouldn't be able to create any instance variables using
define_method. I thought any @ variables in a proc would

refer

to the @ variable in the original context, but

define_method

apparently rebinds them to the object.

I always remind myself that the binding of "self" changes -
even for each
method invocation. This explains pretty good why this works
as it should.

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.

I think of self as a dynamic variable, outside of lexical scope
and that makes me think..

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

... would dynamic variables be enough? Christian Neukirchen has a nifty implementation of them on his blog.

<snip>

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.

if you define a method in a class_eval/module_eval block on object X ruby will define it in instances of X while if you use instance_eval you'd define the method on the object X

···

--- Robert Klemme <bob.news@gmx.net> wrote:

--- nobu.nokada@softhome.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.

···

--- Robert Klemme <bob.news@gmx.net> wrote:

__________________________________
Do you Yahoo!?
Yahoo! Mail - Helps protect you from nasty viruses.
http://promotions.yahoo.com/new_mail

From what I saw, this didn't seem much different than another
space for global variables. The main ability I was wanting was
to be able to replace local variables with their current value
in a proc. I think this would make the ugly *eval(string)
methods rarely needed. I just looked through the stdlib and
found almost every occurence of *eval(string) and found almost
every one looks kind of like this:

name = ...
var = ...
eval("def #{name} .... #{var} .... end")

This would work:

name = ...
var = ...
define_method(name.to_sym,proc{.... var ....}.unbind)

assuming that Proc#unbind replaced "var" with its current
value.

A define_class_method method would also be useful. Otherwise
there would be no equivalent to the above when doing eval("def
self.#{name} .... end").

···

--- gabriele renzi <surrender_it@remove-yahoo.it> wrote:

Eric Mahurin ha scritto:
> 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

... would dynamic variables be enough? Christian Neukirchen
has a nifty
implementation of them on his blog.

__________________________________
Discover Yahoo!
Find restaurants, movies, travel and more fun for the weekend. Check it out!
http://discover.yahoo.com/weekend.html

Eric Mahurin 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.

I see. Although I don't have a use case for this at hand and in fact
never missed that. But that might be just my personal experience.

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?

Not really (at least to my eyes). Also, there are some issues:

- I don't know what nO_element_def does exactly, but it will have to be
rewritten to not create a string with ruby code

- Your version might be less efficient.

- There might be subtle differences because "element" is pulled into the
closure

- Also, unbind_locals will remove "element" from the procs bindings

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

Why do you think that self is special? If there is a general mechanism to
transfer state (i.e. bindings) into a binding, any variable can be
rebound. I imagine something like

proc.binding.bind(:self => whatever, :foo => "bar")
eval("self", proc.binding) # -> whatever
eval("foo", proc.binding) # -> "bar"

<snip/>

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.

Definitely.

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.

Since a class method is just an instance method of the class:

class Foo;end

=> nil

class <<Foo
  define_method(:bar) {"bar"}
end

=> #<Proc:0x10185860@(irb):7>

?> Foo.bar
=> "bar"

Thanks for the interesting exchange!

Kind regards

    robert

···

--- Robert Klemme <bob.news@gmx.net> wrote:

>> 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,attributes)
> }.unbind_locals # replace element with constant
> )
> end
>
> Much cleaner, huh?

Not really (at least to my eyes). Also, there are some
issues:

- I don't know what nO_element_def does exactly, but it will
have to be
rewritten to not create a string with ruby code

Yep. I wasn't paying attention very well. Here is its
definition (this is from cgi.rb, BTW):

def nOE_element_def(element, append = nil)
    s = <<-END
        "<#{element.upcase}" + attributes.collect{|name, value|
            next unless value
            " " + CGI::escapeHTML(name) +
            if true == value
                ""
            else
                '="' + CGI::escapeHTML(value) + '"'
            end
        }.to_s + ">"
    END
    s.sub!(/\Z/, " +") << append if append
    s
end
def nO_element_def(element)
   nOE_element_def(element, <<-END)
       if block_given?
           yield.to_s + "</#{element.upcase}>"
       else
           ""
       end
   END
end

Here would be the evaluating (instead of generating) version:

def nOE_element_def(element,attributes)
    "<#{element.upcase}" + attributes.collect{|name, value|
        next unless value
        " " + CGI::escapeHTML(name) +
        if true == value
            ""
        else
            '="' + CGI::escapeHTML(value) + '"'
        end
    }.to_s + ">"
end
def nO_element_def(element,attributes)
    nOE_element_def(element,attributes) +
    if block_given?
        yield.to_s + "<#{element.upcase}>"
    else
        ""
    end
end

- Your version might be less efficient.

If you flatten the hierarchy, you should be able to get the
same efficiency:

for element in %w[ HTML HEAD BODY P PLAINTEXT DT DD
                   LI OPTION tr th td ]
  define_method(element.downcase.to_sym ,
    proc { |attributes={}|
      "<#{element.upcase}" + attributes.collect{|name, value|
        next unless value
        " " + CGI::escapeHTML(name) +
        if true == value
          ""
        else
          '="' + CGI::escapeHTML(value) + '"'
        end
      }.to_s + ">" +
      if block_given?
        yield.to_s + "<#{element.upcase}>"
      else
        ""
      end
    }.unbind_locals # replace element with constant
  )
end

- There might be subtle differences because "element" is
pulled into the
closure

- Also, unbind_locals will remove "element" from the procs
bindings

I'm assuming that unbind_locals will simply replace any local
variables (external to the proc) with what their current value
is: element will become "HTML", "HEAD", "BODY", etc.

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

Why do you think that self is special? If there is a general
mechanism to
transfer state (i.e. bindings) into a binding, any variable
can be
rebound. I imagine something like

proc.binding.bind(:self => whatever, :foo => "bar")
eval("self", proc.binding) # -> whatever
eval("foo", proc.binding) # -> "bar"

I was assuming that with local variables, you just be moving
the value from one binding to another - not aliasing. The
problem is that you can't assign to "self". If you really
could do the above, then this:

binding.bind(:self => whatever)

would be equivalent to:

self = whatever

I don't that would be a trivial thing to implement. But, if
this "bind" created a new binding (i.e. non-destructive instead
of destructive), it would seem more feasible:

whateverBinding = binding.bind(:self => whatever)
whateverBinding.self.object_id==whatever.object_id

But then you are back to where you started - you still have a
bind the proc to a different binding (probably returning a new
proc).

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

Since a class method is just an instance method of the class:

>> class Foo;end
=> nil
>> class <<Foo
>> define_method(:bar) {"bar"}
>> end

Thanks! That works, but I wanted the proc to have visibility
to the local variables. I think this would be more useful:

class Foo;end
(class<<Foo;self;end).send(:define_method,:bar) {"bar"}

Thanks for the interesting exchange!

and thanks for your ideas.

... back to my original topic - making a duck. For my stuff, I
think I've decided to have 2 ways of doing it:

# make a duck using methods from obj
myDuck = obj.duck(newSym, oldSym, ...)

# make a duck using arbitrary procs
myDuck = duck(methSym => methProc, ...)

One of the applications I'm looking at now is for a method that
looks like this:

Cursor#scan(value)

where value is String/Array like. All it needs is to respond
to #[int] which should return an object that responds to #==.
Although this #scan may look like it just matches to a verbatim
String/Array, you could also do something like this to match to
some digits:

# make == look like ===
digit = (?0..?9).duck(:==,:===)
# match to a string of 4 digits
# Proc responds to like a String/Array
cursor.scan(proc{|i|(i<4)? digit : nil})

Do people do things like this with duck-typing? Or are most
just all talk. Doing something like the above is where I see
the power.

···

--- Robert Klemme <bob.news@gmx.net> wrote:

__________________________________
Discover Yahoo!
Use Yahoo! to plan a weekend, have fun online and more. Check it out!
http://discover.yahoo.com/

Hi,

At Thu, 9 Jun 2005 01:30:53 +0900,
Eric Mahurin wrote in [ruby-talk:144892]:

# make == look like ===
digit = (?0..?9).duck(:==,:===)
# match to a string of 4 digits
# Proc responds to like a String/Array
cursor.scan(proc{|i|(i<4)? digit : nil})

It would be called as `alias', I guess.

···

--
Nobu Nakada

I don't care too much what the method names are. Below is the
implementation I was thinking. This gives you 3 ways to make a
"duck" (a minimal object for a duck-typed argument of a
method):

digit = (?0..?9).duck(:==,:include?,:to_s,:inspect)
alpha = Object.duck(size: proc{26}, :== =>
(?a..?z).method(:===) )
test = Object.duck(:hi) {puts "hello world!"}

Any chance of getting something like this in the standard lib?
Your "Behavior" implementation is fine too.

class Object
    def duck(*new_old)
        obj = Object.new
        klass = (class<<obj;self;end)
        until new_old.empty?
            new,old = new_old.slice!(0,2)
            klass.send(:define_method,new,&self.method(old))
        end
        obj
    end
    def self.duck(methods,&block)
        obj = self.new
        klass = (class<<obj;self;end)
        if block
            klass.send(:define_method,methods,&block)
        else
            methods.each { |name,proc|
                klass.send(:define_method,name,&proc)
            }
        end
        obj
    end
end

···

--- nobuyoshi nakada <nobuyoshi.nakada@ge.com> wrote:

Hi,

At Thu, 9 Jun 2005 01:30:53 +0900,
Eric Mahurin wrote in [ruby-talk:144892]:
> # make == look like ===
> digit = (?0..?9).duck(:==,:===)
> # match to a string of 4 digits
> # Proc responds to like a String/Array
> cursor.scan(proc{|i|(i<4)? digit : nil})

It would be called as `alias', I guess.

--
Nobu Nakada

__________________________________
Discover Yahoo!
Use Yahoo! to plan a weekend, have fun online and more. Check it out!
http://discover.yahoo.com/