On 8/31/07, Dr.Ruud <[EMAIL PROTECTED]> wrote: snip > This is nice content, but not presented well, so I wonder how many > people take the time to read and grok it. > > Maybe you can transform it into an article, maybe both on this list and > on PerlMonks? > > (and please give away the answers :) snip
An article would be redundant, we already have Tom Christiansen's masterful article "Far More Than Everything You've Ever Wanted to Know about Prototypes in Perl"*. It examines prototypes in depth and shows many of the problems (my examples only show two of them). As for the answers, > > sub foo ($) { When reading this a naive reader thinks foo takes one argument. This, while true, is not what the prototype is saying. It is saying that foo takes a scalar argument. This means anything passed to the function will be put in scalar context. So, if we pass an array > > foo(@a); We are effectively saying foo(scalar @a); That is we are passing the number of elements in @a not @a itself. > > foo(@a[0 .. $#a]); Again, we are seeing the effects of scalar context, this time on a list (a slice is list not an array). This means that the last element of the list is passed to foo (lists in scalar context yield the last element**). > > my $sub = \&foo; > > $sub->(@a); > > &foo($a[0], $a[1], $a[2]); These both are ways to avoid the prototype check altogether. I don't know why references to functions don't trigger prototype checking given that it is legal, but useless, to include them with an anonymous subroutine: my $sub = sub ($) { print "args: @_\n" }; $sub->(1,2,3); #not an error I assume this is because prototypes are checked at compile time rather than runtime. I also don't know why the decision was made that calling functions with & should avoid prototype checking, but I assume it was because the following was a common pattern once: sub foo ($) { my $n = shift; return $n + 5; } sub bar ($) { die if $_[0] > 10; &foo; #call foo with bar's arguments } What this all comes down to is that prototypes in Perl are not meant to be used to control how many arguments a function takes, but rather what context the function imposes on the code around it. The fact that the parser kicks out an error if the context is not met is a side effect, not the purpose. And while Larry may have said "The argument against using an operator for other than its primary purpose strikes me the same as the old argument that you shouldn't have sex for other than procreational purposes. Sometimes side effects are more enjoyable than the originally intended effect.", abusing the side effect is likely to get you into trouble (STDs, babies, poorly behaving code, etc.). * http://library.n0i.net/programming/perl/articles/fm_prototypes/ ** I assume this is so that sequences work: my $a = (func_with_side_effect(), other_side_effect(), result()); -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] http://learn.perl.org/