Slash Boxes
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

Aristotle (5147)


Blah blah blah blah blah []

Journal of Aristotle (5147)

Monday October 15, 2007
09:02 PM

How Perl’s dereferencing syntax is unnecessarily awful

[ #34686 ]

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.]

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
More | Login | Reply
Loading... please wait.
  • my @x;
    undef @x;

    my $x = [];
    undef @$x;
    undef $x;

    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.

    • 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.