diff options
author | David Golden <dagolden@cpan.org> | 2010-09-09 17:22:02 -0400 |
---|---|---|
committer | David Golden <dagolden@cpan.org> | 2010-10-31 21:16:21 -0400 |
commit | cba5a3b05660d6a40525beb667a389a690900298 (patch) | |
tree | 4cb5d682634ed416c8b77adb57765035314d1103 /opcode.h | |
parent | f64c9ac53bc4a5fa5967c92e98d7b42cca1ce97b (diff) | |
download | perl-cba5a3b05660d6a40525beb667a389a690900298.tar.gz |
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
Diffstat (limited to 'opcode.h')
-rw-r--r-- | opcode.h | 21 |
1 files changed, 18 insertions, 3 deletions
@@ -399,6 +399,9 @@ EXTCONST char* const PL_op_name[] = { "lock", "once", "custom", + "reach", + "rkeys", + "rvalues", }; #endif @@ -772,6 +775,9 @@ EXTCONST char* const PL_op_desc[] = { "lock", "once", "unknown custom operator", + "each on reference", + "keys on reference", + "values on reference", }; #endif @@ -1159,6 +1165,9 @@ EXT Perl_ppaddr_t PL_ppaddr[] /* or perlvars.h */ Perl_pp_lock, Perl_pp_once, Perl_unimplemented_op, /* Perl_pp_custom */ + Perl_pp_rkeys, /* Perl_pp_reach */ + Perl_pp_rkeys, + Perl_pp_rkeys, /* Perl_pp_rvalues */ } #endif #ifdef PERL_PPADDR_INITED @@ -1327,11 +1336,11 @@ EXT Perl_check_t PL_check[] /* or perlvars.h */ Perl_ck_null, /* lslice */ Perl_ck_fun, /* anonlist */ Perl_ck_fun, /* anonhash */ - Perl_ck_fun, /* splice */ - Perl_ck_fun, /* push */ + Perl_ck_push, /* splice */ + Perl_ck_push, /* push */ Perl_ck_shift, /* pop */ Perl_ck_shift, /* shift */ - Perl_ck_fun, /* unshift */ + Perl_ck_push, /* unshift */ Perl_ck_sort, /* sort */ Perl_ck_fun, /* reverse */ Perl_ck_grep, /* grepstart */ @@ -1543,6 +1552,9 @@ EXT Perl_check_t PL_check[] /* or perlvars.h */ Perl_ck_rfun, /* lock */ Perl_ck_null, /* once */ Perl_ck_null, /* custom */ + Perl_ck_each, /* reach */ + Perl_ck_each, /* rkeys */ + Perl_ck_each, /* rvalues */ } #endif #ifdef PERL_CHECK_INITED @@ -1921,6 +1933,9 @@ EXTCONST U32 PL_opargs[] = { 0x00007b04, /* lock */ 0x00000300, /* once */ 0x00000000, /* custom */ + 0x00001b00, /* reach */ + 0x00001b08, /* rkeys */ + 0x00001b08, /* rvalues */ }; #endif |