Schwern wrote about how ugly “push @{ $foo{bar} }, 3
” is. He proposes the use of autobox::Core to get around this.
Personally, I would have loved if prototypes did nothing else than coerce context and if the compiler assumed that scalars are already references of the appropriate type everywhere a reference is expected, including in prototypes such as “\@
” that want to take a reference.
See, the prototype on push
lets me write “push @foo, $bar
” rather than “push \@foo, $bar
”. But why not also let me write “push $foo, $bar
”? It insists on the right sigil so the type can be checked; I mean, sure, $foo
could be something other than an array ref.
So what? The compile-time check is satisfied if I say “push @$foo, $bar
”, since it knows it will be able to take an array reference if $foo
has dereferenced to an array. But the check whether $foo
dereferences to an array in the first place will be performed at runtime anyhow!
So Perl might as well have let me say “push $foo, $bar
” instead. The check ultimately happens at runtime, no matter what.
But that would allow me to write…
push $foo{bar}, 3; # instead of push @{ $foo{bar} }, 3; # or even delete $foo{bar}{qw( baz quux )} # instead of delete @{ $foo{bar} }{qw( baz quux )} # and in fact, join " ", $foo{bar}[ 3 .. 8 ] # instead of join " ", @{ $foo{bar} }[ 3 .. 8 ]
What purpose do all those spurious @{}
serve? None. They literally add no information whatsoever to the code.
Perl code really does look kinda junky sometimes.
[NB.: those examples aren’t syntax errors in Perl – they just don’t do anything useful, and certainly not what you’d expect. So we can’t retroactively fix this in 5.12 or something. Sigh.]
Personally I think I'd prefer the syntax $a{foo}[] for @{ $a{foo} }; that might even be backwards-compatible. Of course, the heuristic that the parser uses to check the sigils would need completely changing, which would be a nasty job, and you lose the human-heuristic that 'if it starts with @ it's multiple-valued' which was the whole point of the multiple deref operators in the first place.my @x;
undef @x;
my $x = [];
undef @$x;
undef $x;
Re:But it's ambiguous...
Aristotle on 2007-10-16T04:12:58
undef @$x;Good catch – if you need to dereference a ref without using a
[]
or{}
indexing operation, you need the@{}
bracket. I guess that explains the ugly new syntax in Perl 6.I guess
${}
is always necessary by the same token.All in all, not the majority of cases.