Allow push/pop/keys/etc to act on references
authorDavid Golden <dagolden@cpan.org>
Thu, 9 Sep 2010 21:22:02 +0000 (17:22 -0400)
committerDavid Golden <dagolden@cpan.org>
Mon, 1 Nov 2010 01:16:21 +0000 (21:16 -0400)
commitcba5a3b05660d6a40525beb667a389a690900298
tree4cb5d682634ed416c8b77adb57765035314d1103
parentf64c9ac53bc4a5fa5967c92e98d7b42cca1ce97b
Allow push/pop/keys/etc to act on references

All built-in functions that operate directly on array or hash
containers now also accept hard references to arrays or hashes:

  |----------------------------+---------------------------|
  | Traditional syntax         | Terse syntax              |
  |----------------------------+---------------------------|
  | push @$arrayref, @stuff    | push $arrayref, @stuff    |
  | unshift @$arrayref, @stuff | unshift $arrayref, @stuff |
  | pop @$arrayref             | pop $arrayref             |
  | shift @$arrayref           | shift $arrayref           |
  | splice @$arrayref, 0, 2    | splice $arrayref, 0, 2    |
  | keys %$hashref             | keys $hashref             |
  | keys @$arrayref            | keys $arrayref            |
  | values %$hashref           | values $hashref           |
  | values @$arrayref          | values $arrayref          |
  | ($k,$v) = each %$hashref   | ($k,$v) = each $hashref   |
  | ($k,$v) = each @$arrayref  | ($k,$v) = each $arrayref  |
  |----------------------------+---------------------------|

This allows these built-in functions to act on long dereferencing
chains or on the return value of subroutines without needing to wrap
them in C<@{}> or C<%{}>:

  push @{$obj->tags}, $new_tag;  # old way
  push $obj->tags,    $new_tag;  # new way

  for ( keys %{$hoh->{genres}{artists}} ) {...} # old way
  for ( keys $hoh->{genres}{artists}    ) {...} # new way

For C<push>, C<unshift> and C<splice>, the reference will auto-vivify
if it is not defined, just as if it were wrapped with C<@{}>.

Calling C<keys> or C<values> directly on a reference gives a
substantial performance improvement over explicit dereferencing.

For C<keys>, C<values>, C<each>, when overloaded dereferencing is
present, the overloaded dereference is used instead of dereferencing
the underlying reftype.  Warnings are issued about assumptions made in
the following three ambiguous cases:

  (a) If both %{} and @{} overloading exists, %{} is used
  (b) If %{} overloading exists on a blessed arrayref, %{} is used
  (c) If @{} overloading exists on a blessed hashref, @{} is used
19 files changed:
MANIFEST
doop.c
embed.h
op.c
opcode.h
opnames.h
pod/perldelta.pod
pod/perldiag.pod
pod/perlfunc.pod
pod/perlsub.pod
pp.c
pp.sym
proto.h
regen/opcode.pl
t/op/cproto.t
t/op/push.t
t/op/smartkve.t [new file with mode: 0644]
t/op/splice.t
t/op/unshift.t