# Invalid\_arity method similar to method missing?

**URL:** <https://www.ruby-forum.com/t/invalid-arity-method-similar-to-method-missing/52607>\
**Category:** Ruby\
**Created:** [January 17, 2006, 1:42am UTC](https://www.ruby-forum.com/t/invalid-arity-method-similar-to-method-missing/52607 "2006-01-17T01:42:43Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![didier-prophete](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/5daacb/32.png) [@didier-prophete](https://www.ruby-forum.com/u/didier-prophete)\
**Post date:** [January 17, 2006, 1:42am UTC](https://www.ruby-forum.com/t/invalid-arity-method-similar-to-method-missing/52607/1 "2006-01-17T01:42:43Z")

</div>

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…

---

<div class="post-metadata">

**Author:** ![didier-prophete](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/5daacb/32.png) [@didier-prophete](https://www.ruby-forum.com/u/didier-prophete)\
**Post date:** [January 18, 2006, 2:18am UTC](https://www.ruby-forum.com/t/invalid-arity-method-similar-to-method-missing/52607/2 "2006-01-18T02:18:51Z")

</div>

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

> ```
> end
> 
> ```
> 
> -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-forum.com/](http://www.ruby-forum.com/).

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

---

<div class="post-metadata">

**Author:** ![didier-prophete](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/5daacb/32.png) [@didier-prophete](https://www.ruby-forum.com/u/didier-prophete)\
**Post date:** [January 18, 2006, 3:06am UTC](https://www.ruby-forum.com/t/invalid-arity-method-similar-to-method-missing/52607/3 "2006-01-18T03:06:14Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![didier-prophete](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/5daacb/32.png) [@didier-prophete](https://www.ruby-forum.com/u/didier-prophete)\
**Post date:** [January 18, 2006, 4:16am UTC](https://www.ruby-forum.com/t/invalid-arity-method-similar-to-method-missing/52607/4 "2006-01-18T04:16:35Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![didier-prophete](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/5daacb/32.png) [@didier-prophete](https://www.ruby-forum.com/u/didier-prophete)\
**Post date:** [January 18, 2006, 6:23am UTC](https://www.ruby-forum.com/t/invalid-arity-method-similar-to-method-missing/52607/5 "2006-01-18T06:23:00Z")

</div>

On 2006.01.18 11:40, Logan C. wrote:

> 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

> eg  
> have the functions take a hash as its single parameter as I  
> mentioned. Still not quite sure what you are asking.

E

---

<div class="post-metadata">

**Author:** ![didier-prophete](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/5daacb/32.png) [@didier-prophete](https://www.ruby-forum.com/u/didier-prophete)\
**Post date:** [January 20, 2006, 10:40am UTC](https://www.ruby-forum.com/t/invalid-arity-method-similar-to-method-missing/52607/6 "2006-01-20T10:40:49Z")

</div>

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 =   
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
