[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Using define_method isn't the same as defining a method

Yossef Mendelssohn

10/9/2007 2:34:00 PM

I apologize if this has been brought up before. A cursory search
through the archives didn't come up with anything that addressed this
same subject.

I know that creating a Proc (at least a lambda-style Proc) will do
argument checking upon call, and I realize (even though I don't like
it) that those arguments are handled a little oddly:

irb(main):001:0> x = lambda { 'hi' }
=> #<Proc:0x0000ec54@(irb):1>
irb(main):002:0> x.call
=> "hi"
irb(main):003:0> x.call(5)
=> "hi"
irb(main):004:0> x = lambda { |arg| p arg }
=> #<Proc:0x000843a0@(irb):4>
irb(main):005:0> x.call
(irb):4: warning: multiple values for a block parameter (0 for 1)
from (irb):5
nil
=> nil
irb(main):006:0> x.call(5)
5
=> nil
irb(main):007:0> x.call(5,6)
(irb):4: warning: multiple values for a block parameter (2 for 1)
from (irb):7
[5, 6]
=> nil
irb(main):008:0> x = lambda { |arg1, arg2| 'hello' }
=> #<Proc:0x00067674@(irb):8>
irb(main):009:0> x.call
ArgumentError: wrong number of arguments (0 for 2)
from (irb):9
from (irb):9:in `call'
from (irb):9
from :0
irb(main):010:0> x.call(5)
ArgumentError: wrong number of arguments (1 for 2)
from (irb):8
from (irb):10:in `call'
from (irb):10
from :0
irb(main):011:0> x.call(5,6)
=> "hello"
irb(main):012:0> x.call(5,6,7)
ArgumentError: wrong number of arguments (3 for 2)
from (irb):8
from (irb):12:in `call'
from (irb):12
from :0


What I really don't like is how define_method, since it takes a block,
uses this same sort of argument handling. That means

define_method :meth do |arg|
end

is the equivalent of

def meth(*arg)
end

with a warning.

If I want to create a method that takes one argument and acts like a
normal method, what are my choices? Apparently, I get to use only
'def' itself, but that means I need string eval if the method name is
contained in a variable.

Am I wrong? Is there a better way?

--
-yossef


3 Answers

Daniel DeLorme

10/10/2007

0

Yossef Mendelssohn wrote:
> What I really don't like is how define_method, since it takes a block,
> uses this same sort of argument handling. That means
>
> define_method :meth do |arg|
> end
>
> is the equivalent of
>
> def meth(*arg)
> end
>
> with a warning.
>
> If I want to create a method that takes one argument and acts like a
> normal method, what are my choices? Apparently, I get to use only
> 'def' itself, but that means I need string eval if the method name is
> contained in a variable.
>
> Am I wrong? Is there a better way?

This may not be what you're looking for, but if you need define_method
in order to use a variable from the outer scope, you could do something
like:
some_value = 42
define_method :meth do |*args|
_meth(some_value, *args)
end

..which would bomb if the number of args was incorrect

Daniel

Giles Bowkett

10/10/2007 6:30:00 AM

0

Sorry, I'm kind of tired right now, plus an irb dump that big is hard
to read - kinda line-noisey - but just one tiny useful note here. At
Ruby East Ezra Z. from EngineYard did a talk on Ruby performance, and
apparently define_method :foo is slower than def foo not just in the
definition but the invocation as well.

Anyway, he also said eval was slow, which was a bummer for me, because
I do like a bit of eval now and then, but other than the slowness, why
not just use eval? Wrestling with that whole args/blocks thing looks
crazy-making and then some.

--
Giles Bowkett

Blog: http://gilesbowkett.bl...
Portfolio: http://www.gilesg...
Tumblelog: http://giles.t...

Yossef Mendelssohn

10/10/2007 5:38:00 PM

0

On Oct 10, 1:29 am, "Giles Bowkett" <gil...@gmail.com> wrote:
> Sorry, I'm kind of tired right now, plus an irb dump that big is hard
> to read - kinda line-noisey - but just one tiny useful note here. At
> Ruby East Ezra Z. from EngineYard did a talk on Ruby performance, and
> apparently define_method :foo is slower than def foo not just in the
> definition but the invocation as well.
>
> Anyway, he also said eval was slow, which was a bummer for me, because
> I do like a bit of eval now and then, but other than the slowness, why
> not just use eval? Wrestling with that whole args/blocks thing looks
> crazy-making and then some.
>
> --
> Giles Bowkett
>
> Blog:http://gilesbowkett.bl...
> Portfolio:http://www.gilesg...
> Tumblelog:http://giles.t...

It's not something against eval, but more against *string* eval, which
is what I'd need if the method name is held in a variable. And
define_method is RIGHT THERE, so I thought I'd use it. The trouble
comes when you realize it's not the same as def.

You're right about the irb dump. I was just trying to point out the
behavior I was seeing.

--
-yossef