Forum: Ruby Playing with method_missing -- argument list

Aa082c8b00a50928e5860dcd70bf2368?d=identicon&s=25 Tamara Temple (Guest)
on 2013-06-06 14:16
(Received via mailing list)
In https://gist.github.com/tamouse/5719507 , I've been playing around
with using Struct, Enumerable, Comparable and lastly method_missing, and
here's where I got stuck.

At lines 67-69 ("This is going to be fun"), I collect the instance
methods defined in each of Array, Hash, and String, to be able to pass
them along to each of the components of MyClass.

The problem now comes, how many arguments do I pass along as well?

My test example, #keys from Hash, shows my problem. #keys takes no
arguments, but even if the argument list is empty, it's an empty Array,
which of course is something. In some contexts this might be fine, but
in others, not so much.

So, is there a way to detect the number of arguments a method takes?

Or, would it be better to detect the size of args at that point and send
zero, one or many to the attribute's method? Thinking something like:

def check_size(args)
  case args.size
  when 0 ; nil
  when 1 ; args.first
  else args
end

(only maybe not so weak a method name)

AND, is this already a standard function/idiom?
39093dd2b68b68960fecd0fe2b9a5045?d=identicon&s=25 Bartosz Dziewoński (matmarex)
on 2013-06-06 14:48
(Received via mailing list)
You probably want ....send(method, *args) – with a splat before 'args'.

Alternatively, look into Object#method and Method#arity methods:

http://www.ruby-doc.org/core-2.0/Object.html#method-i-method
http://www.ruby-doc.org/core-2.0/Method.html#method-i-arity

irb(main):002:0> [].method(:dup).arity
=> 0
irb(main):010:0> [].method(:delete_at).arity
=> 1
E088bb5c80fd3c4fd02c2020cdacbaf0?d=identicon&s=25 "Jesús Gabriel y Galán" <jgabrielygalan@gmail.com> (Guest)
on 2013-06-06 14:56
(Received via mailing list)
On Thu, Jun 6, 2013 at 2:15 PM, Tamara Temple <tamouse.lists@gmail.com>
wrote:
>
> def check_size(args)
>   case args.size
>   when 0 ; nil
>   when 1 ; args.first
>   else args
> end
>
> (only maybe not so weak a method name)
>
> AND, is this already a standard function/idiom?
>


I think you should be calling send with *args:

2.0.0p195 :001 > h = {}
 => {}
2.0.0p195 :002 > args = []
 => []
2.0.0p195 :003 > h.send(:keys, *args)
 => []
2.0.0p195 :004 > h = {:a => 3}
 => {:a=>3}
2.0.0p195 :005 > h.send(:keys, *args)
 => [:a]

Jesus.
Aa082c8b00a50928e5860dcd70bf2368?d=identicon&s=25 Tamara Temple (Guest)
on 2013-06-07 05:15
(Received via mailing list)
Bartosz Dziewoński <matma.rex@gmail.com> wrote:
> You probably want ....send(method, *args) – with a splat before 'args'.

Indeed. But the major problem turns out to be line 84 -- the super call
should be in an else block and only executed when the other conditions
fall through; where it was it was being executed all the time.

Update: https://gist.github.com/tamouse/5719507

> Alternatively, look into Object#method and Method#arity methods:
>
> http://www.ruby-doc.org/core-2.0/Object.html#method-i-method
> http://www.ruby-doc.org/core-2.0/Method.html#method-i-arity
>
> irb(main):002:0> [].method(:dup).arity
> => 0
> irb(main):010:0> [].method(:delete_at).arity
> => 1

I will make note of those for the future!

> --
> Matma Rex
>

Tamara
Please log in before posting. Registration is free and takes only a minute.
Existing account

NEW: Do you have a Google/GoogleMail, Yahoo or Facebook account? No registration required!
Log in with Google account | Log in with Yahoo account | Log in with Facebook account
No account? Register here.