[ANN] NamedParameters v0.0.0 ('first', :second => 'release')

NamedParameters
is a library for (MRI) ruby 1.8.x that allows you to call a method
with or without named parameters.

Introduction

One thing that is notably lacking from Ruby is the ability to
arbitrarily call methods with named parameters.

Ex in this code:

class A
def method_with_lots_of_parameters param1, p2, p3, p4 = 5, p6 = 7, p7
= 8, p9 = 900
p7
end
end
A.new.method_with_lots_of_parameters 1, 2, 3, 4, 5, 6, 7

can anybody guess what p7 will be when you run this? (a contrived
example, but an example nonetheless).

Previous attempts to overcome this have dealt with using a hash for the
ending argument, and/or *args for parameters. These are somewhat tedious
and also a little error prone, as misspellations aren’t immediately
caught at run-time in the hash example, and parsing is annoying in the
*args example.

Enter named parameters.

With named parameters, you can define your method as you normally would,
and add one line:

class A
def method_with_lots_of_parameters param1, p2, p3, p4 = 5, p6 = 7, p7
= 8, p9 = 900
p7
end

and add this line

create_named_parameters_wrapper :method_with_lots_of_parameters
end

and now you can call it like

A.new.method_with_lots_of_parameters 1, 2, 3, 4, :p7 => 6

And it works as you’d expect.

How it works

It works by creating (in our example above) code equivalent to:

class A

save away the original function

alias :_method_with_lots_of_parameters :method_with_lots_of_parameters

def method_with_lots_of_parameters *args
param1, p2, p3, p4, p6, p7, p9 = args.interpret [:param1, :p2,
:p3], :p4, :p6, :p7, :p9 # parses what you passed it, using the last
hash for named parameters
if p4 == :__not_assigned
p4 = 5
end
if p6 == :__not_assigned
p6 = 7
if p9 == :__not_assigned
p9 = 900
end
_method_with_lots_of_parameters param1, p2, p3, p4, p6, p7, p9 #
call the original function
end
end

Note also that class methods need to be called preceded by ‘self.’, like

class A
def A.class_method1
end
create_named_parameters_wrapper :‘self.class_method1’
end
[to satisfy parseTree’s semantics.]

Also note that you must continue naming parameters once you start naming
them.
[i.e. method_with_lots_of_parameters :param1 => 2, 2, 3 is not allowed],
to help disambiguate which parameter is which [idea stolen from Python].

Many thanks to the parse tree and ruby2ruby crew for making this
possible.

In my own use of it I have seen increased code readability and
understandability, especially for methods that take more than a few
parameters.

Note also that if your current method takes an ending hash then this
won’t work, as it uses the ending hash for named parameters.

How to install

sudo gem install ruby2ruby # pre requisite
svn co
http://ruby-roger-useful-functions.googlecode.com/svn/trunk/arg_parser/v2
named_args
require ‘named_args/create_named_parameters_wrapper’
… # code as usual, adding create_named_parameters_wrapper calls to
functions you’d like to be able to have this functionality.

Feedback welcome.

This is just an early release as I wanted to publish in case it were
useful to anyone.

Take care.
=R

On Jul 17, 2008, at 10:54 PM, Roger P. wrote:

This is just an early release as I wanted to publish in case it were
useful to anyone.

i did something vaguely similar a while back

http://codeforpeople.com/lib/ruby/parseargs/parseargs-0.3.0/README

but didn’t end up using it much. thought you might be interested in
the ideas or impl - your project looks quite interesting - 3 cheers
for ruby2ruby.

regards.

a @ http://codeforpeople.com/

i did something vaguely similar a while back

http://codeforpeople.com/lib/ruby/parseargs/parseargs-0.3.0/README

but didn’t end up using it much. thought you might be interested in
the ideas or impl - your project looks quite interesting - 3 cheers
for ruby2ruby.

Cool stuff. I had never thought of incrementing type conversions.
Haven’t done anything like that since I built a VM back at BYU in the
undergrad years :stuck_out_tongue:

Class checking also has potential. I’ll poke around there and steal
some code sometime if anyone gets around to wanting that feature.

I think you and I both ran into similar problems with constructing this
type of thing. It ends up being somewhat unnatural to use [hopefully
less so with the latest incantation] :slight_smile:

I did notice that Matz apparently plans on using something very similar
to an ending hash for named parameters for 2.0 [1].
We’ll have to see what the future holds.

=R

[1]

I did notice that Matz apparently plans on using something very similar
to an ending hash for named parameters for 2.0 [1].

I think what was meant is this:

def foo(a, args)
p a, args[:b], args[:c] || ‘nope’, args[:d] || ‘yepp’
end
foo 1, :d => 4, :c => 3

In ruby 1.9, due to the new hash syntax, this can be also written as:
foo 1, d: 4, c: 3

Which almost looks like names arguments.

ThoML wrote:

I think what was meant is this:

def foo(a, args)
p a, args[:b], args[:c] || ‘nope’, args[:d] || ‘yepp’
end
foo 1, :d => 4, :c => 3

In ruby 1.9, due to the new hash syntax, this can be also written as:
foo 1, d: 4, c: 3

Which almost looks like names arguments.

Possibly. Kind of hard to tell from interview transcript notes :slight_smile:
My hope is that it’ll be more than just ending hash based, but will
support naming the variable names themselves.

def foo(a, b)
end

foo 3, b: 4

Thanks!
-R

On Jul 18, 2008, at 3:13 PM, Roger P. wrote:

Possibly. Kind of hard to tell from interview transcript notes :slight_smile:
My hope is that it’ll be more than just ending hash based, but will
support naming the variable names themselves.

def foo(a, b)
end

foo 3, b: 4

IDL does this and it’s a pain for most situations, for instance

def foo a, b
bar( … )
end

def bar b, a
end

foo a : 4, b : 2

now foo has to have a method to return the named vars to bar, kinda
like *argv, but much more sophisticated, drastically reducing the
ability the sling around arrays and hashes in methods, especially for
method forwarding. then there is the issue of required vs optional
parameters… and code like this

def foo options = {}
add_defaults_to options
bar options
end

etc

basically i’ve personally found languages with real named parameters
leaving me wishing they were simply hash based. my 2 cts.

a @ http://codeforpeople.com/

On Jul 19, 2008, at 3:13 PM, Roger P. wrote:

My recommendation would be to be able to specify which methods have
named arguments, so you know to expect them, and how to deal with
them.
Thoughts?

:slight_smile:

no thoughts other than: ‘better matz than me!’

cheers.

a @ http://codeforpeople.com/

On Jul 19, 5:13 pm, Roger P. [email protected] wrote:

But how that would interplay with *args, I don’t know.

My recommendation would be to be able to specify which methods have
named arguments, so you know to expect them, and how to deal with them.
Thoughts?

All I want is:

def foo(*args, **keys)

end

I am sooooooooooooooooooooooooooooo tired of:

def foo(*args_and_keys)
keys = (Hash===args_and_keys.last ? args.pop : {})

end

T.

Trans wrote:

All I want is:

def foo(*args, **keys)

end

I could write you one that is
class A
def foo(args, keys)
# keys is always a hash, args an array
end

def bar(args, keys)
end

create_args_keys_wrappers # creates wrappers for functions which have
parameters named args and keys

end

If you’d like it (using ruby2ruby)
-R

IDL does this and it’s a pain for most situations, for instance

def foo a, b
bar( … )
end

def bar b, a
end

foo a : 4, b : 2

now foo has to have a method to return the named vars to bar, kinda
like *argv, but much more sophisticated, drastically reducing the
ability the sling around arrays and hashes in methods, especially for
method forwarding. then there is the issue of required vs optional
parameters… and code like this

def foo options = {}
add_defaults_to options
bar options
end

etc

Yeah it definitely would reduce the ability to have ones own ending
hash.
That being said, you can always just pass on arguments in the standard
way, a la

def foo(a, b)
bar(a, b)
end

But how that would interplay with *args, I don’t know.

My recommendation would be to be able to specify which methods have
named arguments, so you know to expect them, and how to deal with them.
Thoughts?

:slight_smile:
-R

basically i’ve personally found languages with real named parameters
leaving me wishing they were simply hash based. my 2 cts.

a @ http://codeforpeople.com/