Without spending several pages trying to explain myself, I have a need
to do something like this:
def method_missing(method_name, *parameters)
@method_name = method_name
@parameters = parameters
end
. . . many lifetimes later:
send(@method_name, @parameters)
This sorta works - except that @parameters is, rather than a
collection of bare parameters, an array containing them, which the
method being called via send() is not expecting. I'm unsure how to
pull all the contents out of @parameters and make each an individual
bare argument to pass in send(), and very importantly, not pass
anything there if @parameters is empty.
Any ideas?
I know this may seem like a weird thing to be trying to do, but it's
necessary. Trying to explain why I need to do this would literally
take several pages of text. I'm hoping I can avoid the "you shouldn't
be trying to do this" argument and just figure out a way to do it.
Oh, wow - so * turns an array into a list of arguments? I can't find a
reference to this behavior. Pickaxe talks about using * with array
arguments, which is the opposite, isn't it?
Can you tell me where I could find more about this usage?
Oh, wow - so * turns an array into a list of arguments? I
can't find a reference to this behavior. Pickaxe talks about
using * with array arguments, which is the opposite, isn't it?
Can you tell me where I could find more about this usage?
Not specifically, but as I recall, its usage is restricted just to the
situation the poster described - when you're trying to pass a list of
arguments to a method that allows a variable number of arguments as
discrete arguments intstead of list.
Actually, the * here (David A. Black calls it the "unary unarray
operator") is really a feature of Ruby's parallel assignments.
a, b = 1, 2
Parameter passing in Ruby works just like parallel assignment from the
actual parameters to the formals.
Now where does * fit in. You can use it on either the right or left
hand side of a parallel assignment, for example:
a, b = *[1, 2]
sets a to 1 and b to 2. Where
*a = 1, 2
sets a to [1, 2]
and on the left hand side you can have both one or more variables, and
a final "splatted" one.
a, b, *c = *(1..5)
sets a to 1, b to 2, and c to [3,4,5]
Note that the * implicitly converts what follows to an array if
possible, in Ruby 1.8.x this is done using the to_ary method if the
object implements it, in Ruby 1.9 a new to_splat method is used which
implemented in fewer classes, so fewer values get converted.