[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

invalid_arity method similar to method missing ?

didier.prophete

1/17/2006 12:07:00 AM

all,

Is there a function similar to method_missing when an existing method is
called with the wrong number of arguments ?

Suppose I have a class:
class MyClass
def my_func(var1, var2)
end
end

And then I end up calling:
MyClass.new.my_func

As expected, I end up getting an ArgumentError exception ('wrong number
of arguments...). Is there a way to catch these... something like a
'method_missing' (method_missing doesn't get called since the method
exists...), but which would work for wrong number of arguments.

-Didier

ps: obviously, for simple problems, I could end up using some default
argument values, but it won't work for the (real and more complex)
problem I am trying to solve...

--
Posted via http://www.ruby-....


7 Answers

Logan Capaldo

1/18/2006 12:42:00 AM

0


On Jan 16, 2006, at 7:06 PM, Didier Prophete wrote:

> all,
>
> Is there a function similar to method_missing when an existing
> method is
> called with the wrong number of arguments ?
>
> Suppose I have a class:
> class MyClass
> def my_func(var1, var2)
> end
> end
>
> And then I end up calling:
> MyClass.new.my_func
>
> As expected, I end up getting an ArgumentError exception ('wrong
> number
> of arguments...). Is there a way to catch these... something like a
> 'method_missing' (method_missing doesn't get called since the method
> exists...), but which would work for wrong number of arguments.
>
> -Didier
>
> ps: obviously, for simple problems, I could end up using some default
> argument values, but it won't work for the (real and more complex)
> problem I am trying to solve...
>
> --
> Posted via http://www.ruby-....
>


you could let your function be called with any number of arguments
and then worry about it. Probably not what you were looking for though.

eg

def my_func(*args)
var1, var2 = *args
...
end



didier.prophete

1/18/2006 1:30:00 AM

0

Hi Logan,

Thanks for your reply. Well, that doesn't solve my exact problem, but
it's something I'll keep in mind.

Here is actually what I am trying to do. I have these functions which
get their arguments from a 'request' object. Each argument is being
extracted one by one like this:

def f1
arg1 = requests[:arg1]
arg2 = requests[:arg2]
<do some work with arg1, arg2>
end

These functions are called by another class which populates the request
object (actually this is some rails code but the problem is not bound to
rails itself...). Now obviously, this is a little bit of a pain. It
would be much easier to simply write all these function like this, with
real parameters:

def f1(arg1, arg2)
<do some work with arg1, arg2>
end
(I am using f1, and arg1 and arg2, but actually you have more than one
of these functions and the number of arguments is variable...)

So my initial idea was to do something like:
if the caller class calls f1 with the wrong number of argument (zero
in my case):
look at the names of the parameters of the f1
extract value for these arguments from the request object
call f1 with the right parameters
end

Now it turns out that the caller class always uses 'send' to call f1, so
I don't quite need a generic 'invalid_arity' method anymore since I can
just check for the arity of the function being called right before using
'send'

But now my new problem is trying to get the argument names of a given
function. I haven't found a way to do that... I posted a msg on this
forum but didn't get any reply so far...

The best I can do is get a handle to the 'method' object. Something
like:
meth = self.method(:f1)

But I am stuck there... I would need something like:
meth.arg_list
which would return [ :arg1, :arg2 ], or something like that.

I am not even sure this is possible in ruby...

-Didier

--
Posted via http://www.ruby-....


Tim Hunter

1/18/2006 1:40:00 AM

0

Didier Prophete wrote:
> Hi Logan,
>
> Thanks for your reply. Well, that doesn't solve my exact problem, but
> it's something I'll keep in mind.
>
> Here is actually what I am trying to do. I have these functions which
> get their arguments from a 'request' object. Each argument is being
> extracted one by one like this:
>
> def f1
> arg1 = requests[:arg1]
> arg2 = requests[:arg2]
> <do some work with arg1, arg2>
> end
>
> These functions are called by another class which populates the request
> object (actually this is some rails code but the problem is not bound to
> rails itself...). Now obviously, this is a little bit of a pain. It
> would be much easier to simply write all these function like this, with
> real parameters:
>
> def f1(arg1, arg2)
> <do some work with arg1, arg2>
> end
> (I am using f1, and arg1 and arg2, but actually you have more than one
> of these functions and the number of arguments is variable...)
>
> So my initial idea was to do something like:
> if the caller class calls f1 with the wrong number of argument (zero
> in my case):
> look at the names of the parameters of the f1
> extract value for these arguments from the request object
> call f1 with the right parameters
> end
>
> Now it turns out that the caller class always uses 'send' to call f1, so
> I don't quite need a generic 'invalid_arity' method anymore since I can
> just check for the arity of the function being called right before using
> 'send'
>
> But now my new problem is trying to get the argument names of a given
> function. I haven't found a way to do that... I posted a msg on this
> forum but didn't get any reply so far...
>
> The best I can do is get a handle to the 'method' object. Something
> like:
> meth = self.method(:f1)
>
> But I am stuck there... I would need something like:
> meth.arg_list
> which would return [ :arg1, :arg2 ], or something like that.
>
> I am not even sure this is possible in ruby...
>
> -Didier
>

Would it work for you to pass a hash to the method? This is a common
Ruby replacement for named arguments.

obj.meth(:arg1 => 'red', :arg2 => 2, :arg3 => [1,2])

def meth(args)
raise ArgumentError if args.length == 0
... and so on
end

Logan Capaldo

1/18/2006 2:40:00 AM

0


On Jan 17, 2006, at 8:30 PM, Didier Prophete wrote:

> The best I can do is get a handle to the 'method' object. Something
> like:
> meth = self.method(:f1)
>
> But I am stuck there... I would need something like:
> meth.arg_list
> which would return [ :arg1, :arg2 ], or something like that.

I don't believe there is a way to get the argument names from inside
ruby. Can you define these methods (f1 and friends) to take a hash
instead?

eg:
f1(:arg1 => 1, :arg2 => 2)

If you can't do this (you didn't write the functions) perhaps you
need a more robust abstraction, something like a class called
Invocation, or Call or something.

eg

class Call
attr_accessor :target, :method_name, :arguments
def argument_names
... # insert code here to list the names of the arguments
end
end

Of course you'll still need a way to generate this list. Perhaps with
RDoc. THis is a little complicated though, ideally you would simply
have the functions take a hash as its single parameter as I
mentioned. Still not quite sure what you are asking.

ES

1/18/2006 4:45:00 AM

0

On 2006.01.18 11:40, Logan Capaldo wrote:
>
> On Jan 17, 2006, at 8:30 PM, Didier Prophete wrote:
>
> >The best I can do is get a handle to the 'method' object. Something
> >like:
> > meth = self.method(:f1)
> >
> >But I am stuck there... I would need something like:
> > meth.arg_list
> >which would return [ :arg1, :arg2 ], or something like that.
>
> I don't believe there is a way to get the argument names from inside
> ruby.

Slightly off-topic, but there is :)

def foo(a, b, c)
local_variables.each {|var| puts "#{var}: #{eval var}"}
end

foo 1, 2, 3

> ... Can you define these methods (f1 and friends) to take a hash
> instead?
>
> eg:
> f1(:arg1 => 1, :arg2 => 2)
>
> If you can't do this (you didn't write the functions) perhaps you
> need a more robust abstraction, something like a class called
> Invocation, or Call or something.
>
> eg
>
> class Call
> attr_accessor :target, :method_name, :arguments
> def argument_names
> ... # insert code here to list the names of the arguments
> end
> end
>
> Of course you'll still need a way to generate this list. Perhaps with
> RDoc. THis is a little complicated though, ideally you would simply
> have the functions take a hash as its single parameter as I
> mentioned. Still not quite sure what you are asking.


E


didier.prophete

1/20/2006 9:04:00 AM

0

Logan,

> I don't believe there is a way to get the argument names from inside
> ruby.

yeah... I am afraid this is impossible in ruby...

> Can you define these methods (f1 and friends) to take a hash
> ...
> mentioned. Still not quite sure what you are asking.

ahah... well, thanks for helping me anyway. I really appreciate that.

Let me try to explain what my goal was:

Think about how controllers are handled in rails for a second. You end
up having methods after methods which are like:

def meth1
name = params[:name]
data = params[:data]
...
end

def meth2
arg1 = params[:arg1]
arg2 = params[:arg2]
arg3 = params[:arg3]
...
end

Well, this is a little tedious, so I wanted to instead declare these as:

def meth1(name, data)
...
end

def meth2(arg1, arg2, arg3)
...
end

(see how the arguments are passed to the methods rather than being
manually extracted from the 'params' object)

Well, it turns out that these controller methods are always called from
the same place, using:
send(action_name)
(where here, action_name is :meth1, or :meth2)

Now, in order to introduce my change and keep the framework working, I
would want to replace this little piece of code by something like:
arg_names = <figure out the argument names for the method I want to
call>
args = arg_names.map { |name| params[name] }
send(action_name, *args)

Or something like that. The idea being that the caller extracts the
parameter values from the 'params' object and invoke the appropriate
method with these parameters...

Now, because getting the argument names of a method might not be
possible in ruby, this whole thing will not work... But hey, thanks for
helping me (thank also to Eero for his slightly off-topic comment :-)

-Didier

--
Posted via http://www.ruby-....


Gene Tani

1/20/2006 2:36:00 PM

0


Eero Saynatkari wrote:
> On 2006.01.18 11:40, Logan Capaldo wrote:
> >
> > On Jan 17, 2006, at 8:30 PM, Didier Prophete wrote:
> >

> > I don't believe there is a way to get the argument names from inside
> > ruby.
>

http://www.zenspider.com/ZSS/Products/...