New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
pulling in stuff from outside the substr lvalue window #6876
Comments
From perl-5.8.0@ton.iguana.beCreated by perl-5.8.0@ton.iguana.be#! /usr/bin/perl -w prints the expected: #! /usr/bin/perl -w however prints: Sure, I can see what's going on here from an implementation point of If the decision is to leave this as is, it would at least like an This lead to a interesting bugs when i was parsing input from a record parse("AAApadBBBpad"); sub parse { sub parts { because I just kept pulling in the padding. Perl Info
|
From @ysthOn Wed, Oct 29, 2003 at 02:06:12AM -0000, "perl-5.8.0@ton.iguana.be (via RT)" <perlbug-followup@perl.org> wrote:
Yes, I'd like to see this addressed for 5.10.0. Issues need to be worked out for how it should work with negative offset or length.
I used my time machine. Rather than document the existing behaviour
You can use foo(scalar substr(...)) to suppress creating an lvalue. |
From @gbarrOn Oct 29, 2003, at 5:55, Yitzchak Scott-Thoennes wrote:
Why would negative offsets be an issue ? When the LV is created any From what I can see what should be needed is for assignment to an LV to Graham. |
From @gbarrOn Oct 29, 2003, at 2:06, perl-5.8.0@ton.iguana.be (via RT) wrote:
It gets worse #! /usr/bin/perl -w prints: a=abcdefg So multiple assigns to the LV with strings that are shorter than the a=abcdefg All tests still pass, so if there are no objections to this patch I Inline Patch--- mg.c.orig Wed Oct 29 08:28:52 2003
+++ mg.c Wed Oct 29 09:20:31 2003
@@ -1744,16 +1744,20 @@
sv_utf8_upgrade(lsv);
sv_pos_u2b(lsv, &lvoff, &lvlen);
sv_insert(lsv, lvoff, lvlen, tmps, len);
+ LvTARGLEN(sv) = sv_len_utf8(sv);
SvUTF8_on(lsv);
}
else if (lsv && SvUTF8(lsv)) {
sv_pos_u2b(lsv, &lvoff, &lvlen);
+ LvTARGLEN(sv) = len;
tmps = (char*)bytes_to_utf8((U8*)tmps, &len);
sv_insert(lsv, lvoff, lvlen, tmps, len);
Safefree(tmps);
}
- else
- sv_insert(lsv, lvoff, lvlen, tmps, len);
+ else {
+ sv_insert(lsv, lvoff, lvlen, tmps, len);
+ LvTARGLEN(sv) = len;
+ }
return 0;
}
Graham. |
From perl5-porters@ton.iguana.beIn article <20031029055542.GA2612@e_n.org>,
Depends on why this actually works, which is currently unclear to me. perl -le ' qde So is this special compile time magic ? If it's purely depending on the |
From @ysthOn Tue, Oct 28, 2003 at 09:55:42PM -0800, Yitzchak Scott-Thoennes <sthoenna@efn.org> wrote:
Sorry, now I see you have parts modifying $_[0], so scalar isn't helpful. |
From @ysthOn Wed, Oct 29, 2003 at 09:56:53AM +0000, Graham Barr <gbarr@pobox.com> wrote:
By visual inspection, looks good. At least one person claimed to be |
From @ysthOn Wed, Oct 29, 2003 at 08:08:37AM +0000, Graham Barr <gbarr@pobox.com> wrote:
That is how it is now, yes. But I can see a case for storing the negative perl -wle'$x = "abcdef"; for (substr($x,-4,-1)) { chop$x; chop$x; print $_ }' |
From @gbarrOn Oct 29, 2003, at 18:58, Yitzchak Scott-Thoennes wrote:
Whether this goes into maint is upto Nick. But I have not seen any Graham. |
From @nwc10On Wed, Oct 29, 2003 at 07:49:44PM +0000, Graham Barr wrote:
A decision can wait until (at least) 5.8.3, I feel. Nicholas Clark |
From perl5-porters@ton.iguana.beIn article <20031029170549.GB3540@e_n.org>,
|
From @ysthOn Wed, Oct 29, 2003 at 09:54:03PM +0000, Nicholas Clark <nick@ccl4.org> wrote:
The reference I'd seen was in the posts by tlhf in this thread: I'm not completely clear that he/she actually understands the current |
From @iabynOn Wed, Oct 29, 2003 at 09:56:53AM +0000, Graham Barr wrote:
Thanks, applied to bleed as change #22414.
-- |
@iabyn - Status changed from 'open' to 'resolved' |
From @ysthOn Sun, Feb 29, 2004 at 04:43:01PM +0000, Dave Mitchell <davem@fdisolutions.com> wrote:
I tried to get some input on this at: http://perlmonks.org/index.pl?node_id=306449 without much success, other than Abigail arguing strongly for backward |
From perl5-porters@ton.iguana.beIn article <20040229200702.GA204@e_n.org>,
So bugs that have a usable side-effect shouldn't be fixed ? From my point of view: - It caused a hard to track down intermittent problem in real code |
From @iabynOn Sun, Feb 29, 2004 at 12:07:02PM -0800, Yitzchak Scott-Thoennes wrote:
How about the following: Inline Patch--- perlfunc.pod- Mon Mar 1 23:41:25 2004
+++ perlfunc.pod Mon Mar 1 23:58:25 2004
@@ -5578,15 +5578,21 @@
parts of the EXPR and return what was there before in one operation,
just as you can with splice().
-If the lvalue returned by substr is used after the EXPR is changed in
-any way, the behaviour may not be as expected and is subject to change.
-This caveat includes code such as C<print(substr($foo,$a,$b)=$bar)> or
-C<(substr($foo,$a,$b)=$bar)=$fud> (where $foo is changed via the
-substring assignment, and then the substr is used again), or where a
-substr() is aliased via a C<foreach> loop or passed as a parameter or
-a reference to it is taken and then the alias, parameter, or deref'd
-reference either is used after the original EXPR has been changed or
-is assigned to and then used a second time.
+Note that the lvalue returned by by the 3-arg version of substr() acts as
+a 'magic bullet'; each time it is assigned to, it remembers which part
+of the original string is being modifed; for example:
+
+ $x = '1234';
+ for (substr($x,1,2)) {
+ $_ = 'a'; print $x,"\n"; # prints 1a4
+ $_ = 'xyz'; print $x,"\n"; # prints 1xyz4
+ $x = '56789';
+ $_ = 'pq'; print $x,"\n"; # prints 5pq9
+ }
+
+
+Prior to Perl version 5.9.1, the result of using an lvalue multiple times was
+unspecified.
=item symlink OLDFILE,NEWFILE
-- The Enterprise successfully ferries an alien VIP from one place to another |
From @hvdsDave Mitchell <davem@fdisolutions.com> wrote: Shouldn't that last one be C< # prints 5pq89 >? Hugo |
From @hvdsGraham Barr <gbarr@pobox.com> wrote: Thank you, that makes it perfectly clear to me. I'd suggest a similar :So the question is which functionality do we want, this or the ability Now that I understand the behaviour being described it seems perfectly Hugo |
From @gbarrOn 2 Mar 2004, at 02:01, hv@crypt.org wrote:
I can see why you say that, but thats not what happens. The reason is As last assignment via the LVALUE was 3 characters long this assignment So the question is which functionality do we want, this or the ability Graham. |
From @nwc10Mmm. I ought to make a decision on this before 5.8.4 On Thu, Oct 30, 2003 at 07:36:44AM -0800, Yitzchak Scott-Thoennes wrote:
It's a bug, right? Nicholas Clark |
From @ysthOn Sat, Mar 06, 2004 at 05:09:21PM +0000, Nicholas Clark <nick@ccl4.org> wrote:
What makes something a bug? It's non-intuitive but consistent, and What do you think: $x = "abc"; $x = "abc"; |
From perl5-porters@ton.iguana.beIn article <20040308163945.GA1284@e_n.org>,
It causes action at a distance if you pass a substr() result #! /usr/bin/perl -wl # suppose user Y tries to use the module like this: It was perfectly reasonable for the author of "process" It was perfectly reasonable for the caller of process But actually the whole string gets consumed, it eats away Leaving this as it was basically means you can never I think the old effect on ONE assign is somewhat |
From @ysthOn Tue, Mar 09, 2004 at 10:46:51AM +0000, Ton Hospel <perl5-porters@ton.iguana.be> wrote:
Not trying to argue that it's not a bug; but you can say: process(scalar substr($a, 1, 3)); to prevent this. Should this be documented? Why does it work? |
From @ysthOn Tue, 9 Mar 2004 07:45:26 -0800, Yitzchak Scott-Thoennes wrote (in part): yst> On Tue, Mar 09, 2004 at 10:46:51AM +0000, Ton Hospel th> It causes action at a distance if you pass a substr() result as an [snippage by /sb] th> But actually the whole string gets consumed, it eats away OUTSIDE the yst> Not trying to argue that it's not a bug; but you can say: yst> process(scalar substr($a, 1, 3)); yst> to prevent this. Should this be documented? Why does it work? Well, as the person most responsible for the bug, I suppose I should chime As to why C<scalar()> avoids the issue, it's because in the cited code That's why/how it works. I don't think it should be documented, really, When these manipulations first got done, C< \keys %h > was a one-shot LV, Hope this helps, --s. |
From @chipdudeAccording to Spider Boardman:
Since scalar is just a directive to change context, I don't see why it |
From @ysthOn Tue, Mar 09, 2004 at 11:16:02AM -0500, Spider Boardman <spider@leggy.zk3.dec.com> wrote:
Looks to me like scalar passes ref-ness down: Perl_ref(pTHX_ OP *o, I32 type) Looks like it's Perl_mod not passing lvalueness down.
I kind of like having an operator that turns off lvalueness. Especially
I don't seem to be able to get an lvalue with \keys %h. The \ forces $ perl -wle'sub foo ($) { print $_[0]; %h = 0..999; print $_[0] } foo(keys %h)' What do you think about ties on lvalues: |
From @ysthOn Tue, Mar 09, 2004 at 11:28:48AM -0500, Chip Salzenberg <chip@pobox.com> wrote:
Are you saying Perl_mod should or should not recurse on an OP_SCALAR's |
From @chipdudeAccording to Yitzchak Scott-Thoennes:
I'm saying it should. Not with great conviction, though. |
From @ysthOn Tue, 9 Mar 2004 09:06:33 -0800, Yitzchak Scott-Thoennes wrote (in part): yst> On Tue, Mar 09, 2004 at 11:16:02AM -0500, Spider Boardman sb> As to why C<scalar()> avoids the issue, it's because in the cited code yst> Looks to me like scalar passes ref-ness down: yst> Looks like it's Perl_mod not passing lvalueness down. Yes, I mis-remembered where in op.c I was making changes back when. It is sb> Thus, it's a better-optimized form of C< '' . substr($a, 1, 3) >. sb> That's why/how it works. I don't think it should be documented, yst> I kind of like having an operator that turns off lvalueness. While I can understand that, I still think Chip's explanation of his $ perl -le 'sub a($){$_[0]x=2} $a="a";a scalar $a;print $a' sb> When these manipulations first got done, C< \keys %h > was a one-shot yst> I don't seem to be able to get an lvalue with \keys %h. The \ forces You did misunderstand my sloppy explanation. However, the behaviour in $ perl -le '%a=(a=>1);$a=\(keys %a=42);$$a=63;$$a=65;print scalar %a' yst> What do you think about ties on lvalues: I think that attempts to stack various types of assignment-intercepting --s. |
From perl5-porters@ton.iguana.beIn article <20040309154526.GB3952@e_n.org>,
It wouldn't "consume" the substr anymore, which supposedly was I could argue this is a bug in "scalar" in fact... |
From @rgsDave Mitchell wrote:
Thanks, applied as #22488. |
From @cpansproutOn Wed Oct 29 10:59:37 2003, ysth wrote:
Unfortunately this never was addressed for 5.10.0. It is getting in the sub myprint { print @_ } so I’m working on it for 5.15.6. See (I’m adding it to this ticket mainly for future reference.) -- Father Chrysostomos |
From @cpansproutOn Sat Dec 03 13:52:09 2011, sprout wrote:
It’s now fixed with commit 83f78d1. -- Father Chrysostomos |
From @cpansproutOn Tue Mar 09 11:42:01 2004, perl5-porters@ton.iguana.be wrote:
Several others have argued the same thing in this ticket. Attached is a -- Father Chrysostomos |
From @cpansproutFrom 04d535cccd4b0ddc50304d151fba13477972d468 Mon Sep 17 00:00:00 2001 As mentioned in ticket #24346, scalar() should not change lvalueness. This also makes it possible to force scalar context in list assignment Inline Patchdiff --git a/op.c b/op.c
index e353015..bccfd06 100644
--- a/op.c
+++ b/op.c
@@ -2001,6 +2001,7 @@ Perl_op_lvalue_flags(pTHX_ OP *o, I32 type, U32 flags)
else if (!(o->op_flags & OPf_KIDS))
break;
if (o->op_targ != OP_LIST) {
+ case OP_SCALAR:
op_lvalue(cBINOPo->op_first, type);
break;
}
diff --git a/t/op/substr.t b/t/op/substr.t
index f93b64c..3d94d4a 100644
--- a/t/op/substr.t
+++ b/t/op/substr.t
@@ -23,7 +23,7 @@ $SIG{__WARN__} = sub {
BEGIN { require './test.pl'; }
-plan(380);
+plan(381);
run_tests() unless caller;
@@ -682,6 +682,13 @@ is($x, "\x{100}\x{200}\xFFb");
}
}
+# Also part of perl #24346; scalar(substr...) should not affect lvalueness
+{
+ my $str = "abcdef";
+ sub { $_[0] = 'dea' }->( scalar substr $str, 3, 2 );
+ is $str, 'abcdeaf', 'scalar does not affect lvalueness of substr';
+}
+
# [perl #24200] string corruption with lvalue sub
{ |
From @cpansproutOn Mon Dec 05 13:43:02 2011, sprout wrote:
I’ve now applied it as d408447. -- Father Chrysostomos |
From @cpansproutOn Tue Dec 13 08:54:22 2011, sprout wrote:
And reverted it as 41b1a11. See ticket #106288 for details. -- Father Chrysostomos |
From [Unknown Contact. See original ticket]On Tue Dec 13 08:54:22 2011, sprout wrote:
And reverted it as 41b1a11. See ticket #106288 for details. -- Father Chrysostomos |
Migrated from rt.perl.org#24346 (status was 'resolved')
Searchable as RT24346$
The text was updated successfully, but these errors were encountered: