# Using define\_method isn't the same as defining a method

**URL:** <https://www.ruby-forum.com/t/using-define-method-isnt-the-same-as-defining-a-method/116766>\
**Category:** Ruby\
**Created:** [October 9, 2007, 4:34pm UTC](https://www.ruby-forum.com/t/using-define-method-isnt-the-same-as-defining-a-method/116766 "2007-10-09T16:34:54Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![Yossef\_M](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/y/a87d85/32.png) [@Yossef\_M](https://www.ruby-forum.com/u/Yossef_M)\
**Post date:** [October 9, 2007, 4:34pm UTC](https://www.ruby-forum.com/t/using-define-method-isnt-the-same-as-defining-a-method/116766/1 "2007-10-09T16:34:54Z")

</div>

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@:1(irb)  
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@:4(irb)  
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@:8(irb)  
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?

---

<div class="post-metadata">

**Author:** ![Yossef\_M](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/y/a87d85/32.png) [@Yossef\_M](https://www.ruby-forum.com/u/Yossef_M)\
**Post date:** [October 10, 2007, 2:01am UTC](https://www.ruby-forum.com/t/using-define-method-isnt-the-same-as-defining-a-method/116766/2 "2007-10-10T02:01:15Z")

</div>

Yossef M. wrote:

> 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

---

<div class="post-metadata">

**Author:** ![Yossef\_M](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/y/a87d85/32.png) [@Yossef\_M](https://www.ruby-forum.com/u/Yossef_M)\
**Post date:** [October 10, 2007, 9:33am UTC](https://www.ruby-forum.com/t/using-define-method-isnt-the-same-as-defining-a-method/116766/3 "2007-10-10T09:33:58Z")

</div>

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

Blog: [http://gilesbowkett.blogspot.com](http://gilesbowkett.blogspot.com)  
Portfolio: [http://www.gilesgoatboy.org](http://www.gilesgoatboy.org)  
Tumblelog: [http://giles.tumblr.com/](http://giles.tumblr.com/)

---

<div class="post-metadata">

**Author:** ![Yossef\_M](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/y/a87d85/32.png) [@Yossef\_M](https://www.ruby-forum.com/u/Yossef_M)\
**Post date:** [October 10, 2007, 7:41pm UTC](https://www.ruby-forum.com/t/using-define-method-isnt-the-same-as-defining-a-method/116766/4 "2007-10-10T19:41:05Z")

</div>

On Oct 10, 1:29 am, “Giles B.” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> –  
> Giles B.
> 
> Blog:[http://gilesbowkett.blogspot.com](http://gilesbowkett.blogspot.com)  
> Portfolio:[http://www.gilesgoatboy.org](http://www.gilesgoatboy.org)  
> Tumblelog:[http://giles.tumblr.com/](http://giles.tumblr.com/)

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.
