diff options
author | David Caldwell <david@porkrind.org> | 2009-11-23 17:24:25 -0800 |
---|---|---|
committer | David Caldwell <david@porkrind.org> | 2010-05-22 02:28:22 -0700 |
commit | 4f4d7508b0c2c114e5f52420e0e87a853c5f642a (patch) | |
tree | 008d80915d83e246892b83fa06e46a3b2e21c6bf /op.c | |
parent | dd9035cd5bdeced1187df399d27d526f3b30194b (diff) | |
download | perl-4f4d7508b0c2c114e5f52420e0e87a853c5f642a.tar.gz |
Add s///r (non-destructive substitution).
This changes s/// so that it doesn't act destructively on its target.
Instead it returns the result of the substitution (or the original string if
there was no match).
In addition this patch:
* Adds a new warning when s///r happens in void context.
* Adds a error when you try to use s///r with !~
* Makes it so constant strings can be bound to s///r with =~
* Adds documentation.
* Adds some tests.
* Updates various debug code so it knows about the /r flag.
* Adds some new 'r' words to B::Deparse.
Diffstat (limited to 'op.c')
-rw-r--r-- | op.c | 14 |
1 files changed, 13 insertions, 1 deletions
@@ -1110,6 +1110,11 @@ Perl_scalarvoid(pTHX_ OP *o) useless = "negative pattern binding (!~)"; break; + case OP_SUBST: + if (cPMOPo->op_pmflags & PMf_NONDESTRUCT) + useless = "Non-destructive substitution (s///r)"; + break; + case OP_RV2GV: case OP_RV2SV: case OP_RV2AV: @@ -2225,6 +2230,11 @@ Perl_bind_match(pTHX_ I32 type, OP *left, OP *right) no_bareword_allowed(right); } + /* !~ doesn't make sense with s///r, so error on it for now */ + if (rtype == OP_SUBST && (cPMOPx(right)->op_pmflags & PMf_NONDESTRUCT) && + type == OP_NOT) + yyerror("Using !~ with s///r doesn't make sense"); + ismatchop = rtype == OP_MATCH || rtype == OP_SUBST || rtype == OP_TRANS; @@ -2238,7 +2248,9 @@ Perl_bind_match(pTHX_ I32 type, OP *left, OP *right) right->op_flags |= OPf_STACKED; if (rtype != OP_MATCH && ! (rtype == OP_TRANS && - right->op_private & OPpTRANS_IDENTICAL)) + right->op_private & OPpTRANS_IDENTICAL) && + ! (rtype == OP_SUBST && + (cPMOPx(right)->op_pmflags & PMf_NONDESTRUCT))) newleft = mod(left, rtype); else newleft = left; |