Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
PerlMonks  

comment on

( #3333=superdoc: print w/replies, xml ) Need Help??

The only one substr ref per string bug I was referring to is demonstrated here using 5.6.1:

P:\test>c:\perl561\bin\perl5.6.1.exe \bin\p1.pl perl> $bigScalar = 'the quick brown fox jumps over the laxy dog';; perl> @lvrefs = map{ \substr $bigScalar, $_->[0], $_->[1] } [0,3], [4,5], [10,5], [16,3], [20,5], [26,4], [31,3], [35,4], [40,3] +;; perl> print $$_ for @lvrefs;; dog dog dog dog dog dog dog dog dog

With the work around being to use string eval to bypass the restriction:

perl> $bigScalar = 'the quick brown fox jumps over the laxy dog';; perl> @lvrefs = map{ eval '\ substr $bigScalar, $_->[0], $_->[1]' } [0,3], [4,5], [10,5], [16,3], [20,5], [26,4], [31,3], [35,4], [40,3] +;; perl> print $$_ for @lvrefs;; the quick brown fox jumps over the laxy dog

If I remember correctly, the original fix for this went in circa 5.8.3?, but there was another problem also, which I forget the details of, but I will try to remember/retrace my path.

There is (IMO) still an existing problem with lvalue refs in 5.8.5, which I thought I raised a perlbug for, but I have lost track of the outcome. The problem is this:

P:\test>c:\perl5.8.5\bin\perl5.8.5.exe \bin\p1.pl perl> $bigScalar = 'the quick brown fox jumps over the laxy dog';; perl> @lvrefs = map{ \substr $bigScalar, $_->[0], $_->[1] } [0,3], [4,5], [10,5], [16,3], [20,5], [26,4], [31,3], [35,4], [40,3] +;; perl> print $$_ for @lvrefs;; the quick brown fox jumps over the laxy dog perl> ${ $lvrefs[ 4 ] } = 'x';; perl> print $bigScalar;; the quick brown fox x over the laxy dog perl> ${ $lvrefs[ 4 ] } = 'xxxxxx';; perl> print $bigScalar;; the quick brown fox xxxxxxr the laxy dog perl> print $$_ for @lvrefs;; the quick brown fox xxxxx r th la y do

Once a lvalue ref has been used in a way that shrinks or grows the target string, it appears to loose track of what part of the string it should now be referring to.

Ie. When the lvref that points to substring 20,5, is assigned to by a single char, it continues to refer to a 5 char long substr start at pos 20. Hence, when a second (longer) assignment is done via that same lvref, instead of expanding the string (as it would the first time), it overlays a part of the string that it shouldn't.

I believe it would be both possible, and more correct, for the lvrefs that are assigned to in such a way that they shrink or expand the original string to have their length value adjusted accordingly so that second and subsequent assignments would only overlay that part of the original string that remains after the first assignment.

perl> $s = 'abcde';; perl> $lv = \ substr $s, 1, 3;; perl> print $$lv;; bcd perl> $$lv = '1234';; perl> print $$lv;; 123 ## The lvref stil refers to a 3 char substring. ## this could be adjusted to reflect the new len +gth.

Ideally, any other lvrefs refering to that part of the string or later parts of the string that would also be affected by the alteration of the strings length would also be adjusted. But I can see that would require keeping track of all lvrefs that point to a given string and inspecting them all each time which would be complex and costly.

But I think adjusting the one assign through would be easy and useful.


Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
"Science is about questioning the status quo. Questioning authority".
The "good enough" maybe good enough for the now, and perfection maybe unobtainable, but that should not preclude us from striving for perfection, when time, circumstance or desire allow.

In reply to Re^5: lhs substr(): refs vs. scalars by BrowserUk
in thread lhs substr(): refs vs. scalars by renodino

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others chilling in the Monastery: (4)
As of 2021-10-25 17:16 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    My first memorable Perl project was:







    Results (89 votes). Check out past polls.

    Notices?