# Named argument passing, and method\_args extension

**URL:** <https://www.ruby-forum.com/t/named-argument-passing-and-method-args-extension/113931>\
**Category:** Ruby\
**Created:** [September 6, 2007, 10:26am UTC](https://www.ruby-forum.com/t/named-argument-passing-and-method-args-extension/113931 "2007-09-06T10:26:15Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![stickstone](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/6f9a4e/32.png) [@stickstone](https://www.ruby-forum.com/u/stickstone)\
**Post date:** [September 6, 2007, 10:26am UTC](https://www.ruby-forum.com/t/named-argument-passing-and-method-args-extension/113931/1 "2007-09-06T10:26:15Z")

</div>

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](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](http://eigenclass.org/hiki.rb?Changes+in+Ruby+1.9#l4) 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.

---

<div class="post-metadata">

**Author:** ![stickstone](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/6f9a4e/32.png) [@stickstone](https://www.ruby-forum.com/u/stickstone)\
**Post date:** [September 6, 2007, 6:47pm UTC](https://www.ruby-forum.com/t/named-argument-passing-and-method-args-extension/113931/2 "2007-09-06T18:47:38Z")

</div>

Method#args has a home now at [http://method-args.rubyforge.org/](http://method-args.rubyforge.org/)  
I released a new version too. It can be installed directly from the  
command line

% sudo gem install method\_args

There are several new methods for more refined sorcery:

% irb -r rubygems

> > require ‘method\_args’  
> > class X; def foo(hello, world = 2, \*blah); end; end  
> > method = X.new.method :foo  
> > =\> #\<Method: X#foo\>  
> > method.required\_args  
> > =\> [:hello]  
> > method.optional\_args  
> > =\> [:world]  
> > method.splat\_arg  
> > =\> :blah  
> > method.args  
> > =\> [:hello, :world, :blah]

ry

---

<div class="post-metadata">

**Author:** ![stickstone](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/6f9a4e/32.png) [@stickstone](https://www.ruby-forum.com/u/stickstone)\
**Post date:** [September 7, 2007, 8:48pm UTC](https://www.ruby-forum.com/t/named-argument-passing-and-method-args-extension/113931/3 "2007-09-07T20:48:35Z")

</div>

On 9/6/07, Brian C. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

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

> I had a look at [eigenclass.org](http://eigenclass.org/hiki.rb?Changes+in+Ruby+1.9#l4) but  
> couldn’t see anything along these lines.

What IS in 1.9 is a new literal syntax for hash arguments:

$ irb1.9  
irb(main):001:0\> def test(arg)  
irb(main):002:1\> p arg  
irb(main):003:1\> end  
=\> nil  
irb(main):004:0\> test(a: “hello”, b: 3)  
{:b=\>3, :a=\>“hello”}  
=\> nil

as an alternative to:

irb(main):005:0\> test(:a =\> “hello”, :b =\> 3)  
{:b=\>3, :a=\>“hello”}  
=\> nil

## This allows all the current code which uses options hashs as a form of named parameters to support a new “nicer” caller syntax without change.

Rick DeNatale

My blog on Ruby  
[http://talklikeaduck.denhaven2.com/](http://talklikeaduck.denhaven2.com/)

---

<div class="post-metadata">

**Author:** ![stickstone](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/6f9a4e/32.png) [@stickstone](https://www.ruby-forum.com/u/stickstone)\
**Post date:** [September 10, 2007, 12:35pm UTC](https://www.ruby-forum.com/t/named-argument-passing-and-method-args-extension/113931/4 "2007-09-10T12:35:42Z")

</div>

Hello,

On Do, 2007-September-06 10:17:11, Brian C. wrote:

> func( \*{:c=\>3, :b=\>2, :a=\>1} ) # =\> [1,2,3] 🙂

Wow, I really like this idea a lot.

I think this could be taken even a bit further,  
by allowing the splat outside method headers:

h = {:c=\>3, :b=\>2, :a=\>1}  
a, b, c = \*h  
p [a, b, c] # =\> [1,2,3]

The most important reason why I like this,  
is because it would give us not only named  
arguments, but named return values too,  
leading to a nice symmetry:

def get\_data  
…  
{:name =\> name, :zip =\> zip}

# the old way would be: [name, zip]

end

# and then we would simply write:

name, zip = get\_data

# or just as well:

zip, name = get\_data # same effect, more robust

Yes, hashes are already used to return multiple values today,  
but I think the clumsy notation (  
d = get\_data  
name = d[:name]  
zip = d[:zip]  
) prevents many programmers from adopting this practice.

To sum up:  
Yes. I would really like to see something like this in Ruby 3.0

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

OK, I would call that the problem of “reverse splatting”.

I.e.: If we allow splat for both arrays and hashes,  
we will be able to determine the type of the splat from the object  
if the operator is on the right-hand side.

But we won’t have any information, if it is on the left-hand side:  
\*x = a, b, c  
This could be interpreted as both  
x = [a, b, c]  
or  
x = {:a=\>a, :b=\>b, :c=\>c}

A simple way to deal with that, would be to declare the old  
interpretation  
(array) as the only one for a LHS-splat.

And the semantics of Brian’s example could be preserved in this  
approach,  
because it not only has a LHS-splat, but also a RHS-splat with it.

Essentially it boils down to:  
\*d = \*{:e=\>5, :f=\>6}

And we just have to assume an internal “splat reduction”, giving:  
d = {:e=\>5, :f=\>6}

However, it might be nice to have a way to force reverse hash splatting,  
for example by a new prefix operator \*\*  
\*\*h = a, b, c

# =\> h = {:a=\>a, :b=\>b, :c=\>c}

… but also inviting cans of trouble, like  
\*\*h = a, b, 42 # result??

# perhaps

# =\> h = {:a=\>a, b=\>b, 2=\>42} (position used as key)

Yes, at this point I really wish that there be a unified Hash-Array  
data structure, as they have in Oz or Lua.

Bye for now

Regards  
Sven
