Quick question - what are the current thoughts about named argument
passing
in future versions of Ruby? I’ve seen it requested in the past but not
much
in the way of concrete proposals.
Those awfully nice Merb people have just come up with a clever idea,
already
implemented as a small C extension. This lets you reflect on the names
of
arguments in a method definition.
require ‘method_args’
class X
def hello(foo, bar)
nil
end
end
x = X.new
meth = x.method(:hello)
meth.args? # => true
meth.args # => [‘foo’, ‘bar’] <<< cool!
This has been released as a Gem, see
http://rubyforge.org/pipermail/merb-devel/2007-September/000239.html
The idea is that instead of writing
def show
id = params[:id]
page = params[:page]
…
end
you should be able to write
def show(id, page=nil)
…
end
with Method#args allowing the desired elements of the params hash to be
picked out automatically and passed in the correct order.
Effectively what you end up is something like a splat call, but with the
arguments in named order as defined by the method definition.
Taking this one step further, has it been considered that splat might be
applied to a hash in the same way? e.g.
def func(a, b, c)
[a, b, c]
end
func( *{:c=>3, :b=>2, :a=>1} ) # => [1,2,3]
I had a look at eigenclass.org but
couldn’t see anything along these lines.
In 1.8, splat does work on a hash, but only by flattening it to an
array
first, which isn’t very useful as the order is arbitary.
irb(main):003:0> def f(a); p a; end
=> nil
irb(main):004:0> f([1,2,3])
[1, 2, 3]
=> nil
irb(main):005:0> f(*{:a=>1,:b=>2})
[[:b, 2], [:a, 1]]
=> nil
Regards,
Brian.
P.S. By symmetry, I’d suggest that any ‘unused’ elements could be
available
as a hash too:
def func(a, b, c=3, *d)
p a, b, c, d
end
func( *{:a=>1, :b=>2, :e=>5, :f=>6} )
1
2
3
{:e=>5, :f=>6}
However this does mean that the receiver of *d would have to be able to
cope
with receiving either an Array or a Hash.