summaryrefslogtreecommitdiff
path: root/opcode.h
diff options
context:
space:
mode:
authorDavid Golden <dagolden@cpan.org>2010-09-09 17:22:02 -0400
committerDavid Golden <dagolden@cpan.org>2010-10-31 21:16:21 -0400
commitcba5a3b05660d6a40525beb667a389a690900298 (patch)
tree4cb5d682634ed416c8b77adb57765035314d1103 /opcode.h
parentf64c9ac53bc4a5fa5967c92e98d7b42cca1ce97b (diff)
downloadperl-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.h21
1 files changed, 18 insertions, 3 deletions
diff --git a/opcode.h b/opcode.h
index b67067536e..c7a304d064 100644
--- a/opcode.h
+++ b/opcode.h
@@ -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