Andrew Rodland skribis 2005-11-07 13:30 (-0500): > If you want to get into personal beliefs, I think that function signatures > are > such a complexity quagmire -- and that they're line-noise ugly to boot.
The nice thing about signatures is that they let you write what you mean. This saves you an entire translation from what you mean to some Perl code that manipulates @_. This translation is hard, and error prone, as is the code that comes from it. I think that even without any introduction to the subtleties of signatures, any newbie with some programming experience will instantly understand the essence of: sub my_join ($sep, [EMAIL PROTECTED]) { foo($sep, @elems); } and method connect ($host, $port = 80) { ... } While this isn't quite so clear: sub my_join { my $sep = shift; foo($sep, @_); } sub connect { croak "..." if @_ < 1; croak "..." if @_ > 2; my ($host, $port) = @_; $port = 80 if not defined $port; ... } Or let's take this simple example: sub convert (:$from, :$to, :$thing) { ... } That isn't quite "my %args = @_;". Yes, that works, but the only real way we keep doing it is that the full solution sucks in plain Perl 5: sub convert { croak "..." if (@_ % 2) != 0; my %args = @_; croak "..." if not exists $args{from}; croak "..." if not exists $args{to}; croak "..." if not exists $args{thing}; my $from = delete $args{from}; my $to = delete $args{to}; my $thing = delete $args{thing}; croak "..." if keys %args; ... } before you shout that I'm doing something wrong, yeah, I've been out of this game for a while. Which only strengthens my point: it's hard to do it right in Perl 5! So, the typical answer is: use a module! Good idea, really, but that still doesn't fix the problem. There are several modules out there that handle argument parsing, that in practice you need to know the subtleties of each of them. And none lets you combine scalar and list context, because only prototypes can do that. I don't have to explain why prototypes suck, and I think you can guess why combining them with a parsing module sucks too. For fun, one example with Params::Check: use Params::Check qw(check); sub convert { croak "..." if (@_ % 2 ) != 0; my %args = @_; check( { from => { required => 1, store => \my $from }, to => { required => 1, store => \my $to }, thing => { required => 1, store => \my $thing }, }, \%args, 1, ); ... } And oh boy, would this all have been VERY different if I wanted to simulate this instead: sub convert (:$from, :$to, :$thing is rw) { ... } I think the complexity of signatures is much less than that of doing the same things without them, with the extra benefit that even beginners will (almost) instantly understand most of it! Juerd -- http://convolution.nl/maak_juerd_blij.html http://convolution.nl/make_juerd_happy.html http://convolution.nl/gajigu_juerd_n.html