I left it off mksref, because I wasn't sure how it should behave. It's an odd one.
I personally believe it should either complain if anything but exactly one argument is passed to it, or try to do something smart in that case, as I tried to, in my example. Another possibility would have been for it to return \[@_] but that would leave with two levels of indirection which is not consistent with the one argument case; further, it would amount to mksref mkaref LIST, so it doesn't make much sense.
Another possibility that springs to mind is the following: if there were an anonymous (circumfix) scalar ref constructor, it would impose scalar context to its arguments. Thus it should behave as follows:
sub mksref { my $x = +(@_)[-1]; \$x }
This looks like a job for prototypes. No, really :).
I can't see how prototypes could help there:
sub mkcref (@) {
my @closed = @_;
return sub { @closed};
}
sub mkaref (@) {
return [@_];
}
The @ prototype does not do anything useful, since it just says that the arguments are an arbitrary list, which is the default anyway.
sub mkhref (%) {
if ( @_%2 ) {
warn "Odd number of elements in mkhref";
return { @_, undef };
}
else {
return {@_};
}
}
There's not a % prototype that I know of. There's a \% one which does something entirely different. If there were I believe it should simply do the evenness check you're doing yourself.
Said this, my own version of mkhref() did something different: took a list and returned a hashref with the elements of that list as keys, and undef values. Given that these subs are supposed to be prefix alternatives to the circumfix [ ], { } and sub { } constructors, and to the non existant scalar ref one, my sub is certainly stupid and yours does the Right Thing™. But in the same vein, I would leave to perl to do its job of checking (if warnings are enabled) evennes:
sub mkhref { {@_} }
|