Create method using define_method with all sort of args?

J

Joshua Muheim

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
 
J

Joshua Muheim

Oh yeah, forgot one...

def new_method(some_param, options = {}, *args, &block)
end

What's the equivalent to this...?
 
M

MonkeeSage

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
 
M

MonkeeSage

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
 
P

Phrogz

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.

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

MonkeeSage

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,598
Members
45,151
Latest member
JaclynMarl
Top