The next version of Method::Signatures on its way to CPAN now has named parameters.
method display( $text is ro, :$justify = 'left', :$enchef = 0 ) { ... }
# $text = "some stuff", $justify = 'left', $enchef = 0 $obj->display( "some stuff" );
# $text = "Things and stuff\n", $justify = 'left', enchef = 1 $obj->display( <<'TEXT', enchef => 1 ); Things and stuff TEXT
method foo( :$this, :$that, $foo?, $bar? ) # illegal
# $foo = "this", $bar = 42 or $this = 42 ? $obj->foo( this => 42 );
method bar( $a, $b?, :$c ) # illegal, ambiguous
# $a = 'c', $b = 42 or is it $c = 42? $obj->bar( c => 42 );
It's be keen to see two more things supported.
First, it'd be nice to say, "Yes, I just want named arguments, but they're all in $_[1] as a hashref. The rest is empty."
$obj->method({ named => 'arguments' });
Secondly, "Yeah, I have positional and named arguments, with all the named arguments in a hashref at the end."
$obj->method($arg1, $arg2, { named => 'args' });
This would cover nearly all my code's methods.
(Maybe I should STFU and WSFC.)
Re:two more common uses
schwern on 2008-10-13T18:32:37
To the hash ref, I don't deny it's common, but I ask why do we do that? One reason is to try and save a copy, if the hash happens to be huge. But they aren't, and if they are do you really want to enumerate all the names? And anyway, breaking the hash ref down into a bunch of scalars wastes all that memory savings anyway.
Another reason is to leave open the possibility of passing in more arguments.
$obj->method({ this => 'that' }, 42);
in which case you're not really passing in named arguments else that new positional argument could just be a named one.
$obj->method({ this => 'that', stuff => 42 });
And you no longer need the hash ref, just make it a hash.
Otherwise, what you're really passing in that hash ref is not named arguments but a lump of data. For example...
method new ($class: \%data, $something_else) {
my $self = bless {%data}, $class;
$self->wibble($something_else);
}To chop up %data into a bunch of scalars makes no sense.
As for the hash-ref at end, unless you have optional positional params its no longer necessary.
method foo ($this, $that,
:$named) {
...
}
$obj->method($arg1, $arg2, named => 'args');Of course, I'm sure I'm missing something important and TMTOWTDI reigns. And there's no real reason it can't handle named arguments as hash refs. The real block is always deciding what the syntax should be. Since it's a good idea to make the signature look like how it's called...
method foo( $this, $that, {:$foo,
:$bar} ); Which opens up the possibility of allowing the named hash-ref params coming first.
method foo( {:$foo,
:$bar}, $this, $that ); Or even the special case "slurp the hash ref off the end, then resolve the possibly optional positionals".
method foo( $this?, $that?, {:$foo,
:$bar} ); In order for any of this to work and remain unambiguous, the hash ref would be required by default.
Re:two more common uses
rjbs on 2008-10-14T19:56:53
Apart from anything else, the biggest argument is:
If I don't have to change the calling semantics, I can actually use this in old code. If I have to update every caller to pass a list rather than a hashref, I am not going to do it. If I can't update my old codebase to use this, I am not likely to start using it for new code, either.
Re:two more common uses
Aristotle on 2008-10-19T22:59:49
One reason is to try and save a copy
The only good reason is that it forces an “Odd number of elements” warning to be emitted from the calling site without having to add any code to the callee. Obviously this does not apply in your module’s case.