# Create method using define\_method with all sort of args?

**URL:** <https://www.ruby-forum.com/t/create-method-using-define-method-with-all-sort-of-args/120976>\
**Category:** Ruby\
**Created:** [November 22, 2007, 10:59am UTC](https://www.ruby-forum.com/t/create-method-using-define-method-with-all-sort-of-args/120976 "2007-11-22T10:59:51Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![josh](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/45deac/32.png) [@josh](https://www.ruby-forum.com/u/josh)\
**Post date:** [November 22, 2007, 10:59am UTC](https://www.ruby-forum.com/t/create-method-using-define-method-with-all-sort-of-args/120976/1 "2007-11-22T10:59:51Z")

</div>

Hi all

I know that one can create new methods using define\_method…

def new\_method  
end

is equivalent to

define\_method(:new\_method) do  
end

def new\_method(some\_param)  
end

is equivalent to

define\_method(:new\_method) do |some\_param|  
end

def new\_method(some\_param, \*args)  
end

is equivalent to

define\_method(:new\_method) do |some\_param, \*args|  
end

But what’s equivalent to…

def new\_method(some\_param, options = {}, \*args)  
end

??? Thanks for help.  
Josh

---

<div class="post-metadata">

**Author:** ![josh](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/45deac/32.png) [@josh](https://www.ruby-forum.com/u/josh)\
**Post date:** [November 22, 2007, 1:52pm UTC](https://www.ruby-forum.com/t/create-method-using-define-method-with-all-sort-of-args/120976/2 "2007-11-22T13:52:16Z")

</div>

Oh yeah, forgot one…

def new\_method(some\_param, options = {}, \*args, &block)  
end

What’s the equivalent to this…?

---

<div class="post-metadata">

**Author:** ![josh](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/45deac/32.png) [@josh](https://www.ruby-forum.com/u/josh)\
**Post date:** [November 23, 2007, 9:01am UTC](https://www.ruby-forum.com/t/create-method-using-define-method-with-all-sort-of-args/120976/3 "2007-11-23T09:01:13Z")

</div>

On Nov 22, 6:52 am, Joshua M. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> What’s the equivalent to this…?

You have to use a predefined function if you want to pass a block,  
e.g,

class A  
def new\_method1(somep, opts={}, \*args, &block)  
p opts  
end  
private  
def \_foo(somep, opts={}, \*args, &block)  
p opts  
end  
public  
define\_method(:new\_method2, instance\_method(:\_foo))  
end

Also, you can’t pass an optional argument to a block, you’d have to  
write something like…

class A  
define\_method(:new\_method3) { |somep, \*args|  
opts = {}  
if args.length \> 0 && args[0].class == Hash  
opts = args[0]  
end  
p opts  
}  
end

Regards,  
Jordan

---

<div class="post-metadata">

**Author:** ![josh](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/45deac/32.png) [@josh](https://www.ruby-forum.com/u/josh)\
**Post date:** [November 23, 2007, 9:24pm UTC](https://www.ruby-forum.com/t/create-method-using-define-method-with-all-sort-of-args/120976/4 "2007-11-23T21:24:07Z")

</div>

On Nov 22, 2007, at 2:59 AM, Joshua M. wrote:

> But what’s equivalent to…
> 
> def new\_method(some\_param, options = {}, \*args)  
> end

define\_method ‘new\_method’ do |some\_param, \*argv|  
options, \*argv = argv  
options ||= {}

…  
end

a @ [http://codeforpeople.com/](http://codeforpeople.com/)

---

<div class="post-metadata">

**Author:** ![josh](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/45deac/32.png) [@josh](https://www.ruby-forum.com/u/josh)\
**Post date:** [November 24, 2007, 3:35am UTC](https://www.ruby-forum.com/t/create-method-using-define-method-with-all-sort-of-args/120976/5 "2007-11-24T03:35:34Z")

</div>

On Nov 23, 2:23 pm, “ara.t.howard” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> define\_method ‘new\_method’ do |some\_param, \*argv|  
> options, \*argv = argv  
> options ||= {}
> 
> …  
> end

Ara,

Isn’t that dangerous in case new\_method is called like:

a.new\_method(“a”, other, args)

…where the optional ‘option’ arg is left out? It seems that your  
version would consume the ‘other’ operand in that case. I think you’d  
need to do something like I posted above to be safe.

Regards,  
Joran

---

<div class="post-metadata">

**Author:** ![josh](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/45deac/32.png) [@josh](https://www.ruby-forum.com/u/josh)\
**Post date:** [November 24, 2007, 5:20am UTC](https://www.ruby-forum.com/t/create-method-using-define-method-with-all-sort-of-args/120976/6 "2007-11-24T05:20:17Z")

</div>

On Nov 23, 7:26 pm, MonkeeSage [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Isn’t that dangerous in case new\_method is called like:
> 
> a.new\_method(“a”, other, args)
> 
> …where the optional ‘option’ arg is left out? It seems that your  
> version would consume the ‘other’ operand in that case. I think you’d  
> need to do something like I posted above to be safe.

Your question implies to me that you think that if I define a method  
like this:  
def foo( name, age=0, weight=170 )  
…  
end  
that I can then call it like this:  
foo( “Gavin”, 175 ) # use default age.

In case I’m properly understanding you, then you should know that you  
cannot do that. You can’t ‘skip’ an optional argument and have other  
optional or non-optional arguments later. So, by definition, the  
‘other’ you use in your example is necessarily the second parameter to  
the method, and thus satisfies the OPs desired functionality.

---

<div class="post-metadata">

**Author:** ![josh](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/45deac/32.png) [@josh](https://www.ruby-forum.com/u/josh)\
**Post date:** [November 24, 2007, 5:36am UTC](https://www.ruby-forum.com/t/create-method-using-define-method-with-all-sort-of-args/120976/7 "2007-11-24T05:36:04Z")

</div>

On Nov 23, 10:16 pm, Phrogz [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> In case I’m properly understanding you, then you should know that you  
> cannot do that.

Err…my brain broke for a minute there (bad brain!), heh. Thanks for  
the correction.

Regards,  
Jordan
