Playing with method_missing -- argument list

In Playing with Struct, Enumerable, and Comparable · GitHub , 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?

You probably want …send(method, *args) – with a splat before ‘args’.

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

irb(main):002:0> [].method(:dup).arity
=> 0
irb(main):010:0> [].method(:delete_at).arity
=> 1

On Thu, Jun 6, 2013 at 2:15 PM, Tamara T. [email protected]
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.

Bartosz Dziewoński [email protected] 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: Playing with Struct, Enumerable, and Comparable · GitHub

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

Class: Object (Ruby 2.0.0)
Class: Method (Ruby 2.0.0)

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

Tamara