I wish that Perl 5 could be smarter about references. I wish I could just give an array reference to functions that only act on arrays and have Perl do the dereferencing for me.
Here is what I have to write today to use array functions on an array reference:
# Given $obj->foo() that returns an array reference
shift @{ $obj->foo };
push @{ $obj->foo }, @stuff;
splice @{ $obj->foo }, 0, 2;
Here is how I wish it would work:
shift $obj->foo; push $obj->foo, @stuff; splice $obj->foo, 0, 2;
Isn't that second block a lot cleaner to read? Getting rid of the @{} declutters the code and, at least for me, it's still clear from the context that I expect the first argument to act like an array.
Likewise, I'd like to have the same magic work for functions like values or keys, which would let me flatten array references or get an index list in a more readable way:
# from this:
for ( @{ $obj->foo } ) { ... }
for ( $#{ $obj->foo } ) { ... }
# to this:
for ( values $obj->foo ) { ... }
for ( keys $obj->foo ) { ... }
I suspect something similar would make sense for hash references, too.
On reflection, I think this would mean that checking that the first argument indeed held an array reference would have to be done at run-time, but I suspect there might be a way within the Perl op-codes to avoid such a checks except when necessary. (Thus, you could still use @{} for a slight bit of hand-optimization, if desired.)
I wish I knew more Perl guts to work on a draft implementation, because right now I think this would be one of the coolest features to see in a future Perl.
8 Comments
Why not use autobox? For example:
for ($obj->foo->values) { ... }—Theory
It's not core. (At least, not yet.) And it works through method resolution, and I don't think the overhead should be necessary for simple array manipulation. autobox is a great tool because Perl isn't smart enough about references.
Theory: Because of the performance penalty.
I quite like the alternative syntax, but only if the run-time speed for shift @whatever is absolutely the same.
I really don't want to pay a speed penalty for some of the most heavily used functions in the entire language.
Amen, the @{ } syntax has always struck me as the ugliest part of Perl by far. Especially for references in a hash
push @{ $foo->{bar}}, 1is really, really ugly. I understand that in the case offor ($foo->{bar}) { ... }there would be an ambiguity, but really, how often do you do this to get the reference in $foo->{bar} in $_?hello,
Even i'm boring about writing/reading the @{ } stuff, i have to say i really appreciate the presence of the sigil because it make the code more readable (@ so you know it's an array) and reliable (@ so perl can crash if not an array).
what i would like to see is @$obj->foo
@mirod: really: i use it daily !
What happens if
$obj->fooreturns multiple values?What will
push foo(), @bar, @bazdo iffooreturns the empty list? And depending on the answer to that one: what will it do if the first element in@baris an array ref?Then, whatever behaviour you pick: how do you explain it to a less experienced programmer who has to maintain some Perl code?
(This feels a little like the Perl 6 RFC process all over…)
A while back I saw a proposal to have
$foo->@mean@{ $foo }, so that your examples would become eg.push $obj->foo->@, @stuff. To me that seems more likely to work without wonderfully strange new corner cases. Though still slightly cumbersome, it still simplifies the syntax (just a postfix, instead of a circumfix around arbitrarily large expressions). And it also has the advantage of being available in places other than a handful of magic built-ins.In your first two examples, I would expect it to work just the exact same way that
@{ $obj->foo }would work iffoo()returned multiple values or an empty list.In your third example, if the first element of
@baris an array ref, it's pushed onto the array, just like normal. I'm only suggesting letting the target of the push be an array reference, because that's the only place where the intention is clear by context.One Trackback
[...] a recent post, I said I wished that Perl's built in functions for array containers would work directly on [...]