in reply to Re^3: regex syntax and idomatic Perl
in thread regex syntax and idomatic Perl

substr is also an lvalue sub, but its return value can also be magic...

$ perl -lwMstrict my $x="abcdefghi"; for (substr $x,1,3) { print; s/c/C/; print; } print $x; my $y = \substr $x,5,3; $$y=~s/g/G/; print $x; __END__ bcd bCd abCdefghi abCdefGhi

Replies are listed 'Best First'.
Re^5: regex syntax and idomatic Perl
by cbeckley (Curate) on Mar 22, 2017 at 23:33 UTC

    For the record, I stared at that piece of code for an entire beer.

    So ... $_ in the for loop, and $y are references ...
    and you could have said

    substr $x,5,3 =~ s/g/G/;

    Instead of

    my $y = \substr $x,5,3; $$y=~s/g/G/;

    For the same result?

      So ... $_ in the for loop, and $y are references

      Not exactly, $_ is an alias to the elements being looped over, not a reference (which would need to be dereferenced), see the first few paragraphs of Foreach Loops. Some more fun with aliases, note how the magic substr lvalue remembers its bounds in the string:

      our ($x,$y) = "Hello, World!"; *y = \substr $x, 7, 5; # alias via glob $y = "substring"; print "<$x>\n"; # prints <Hello, substring!> $y = "Perl"; print "<$x>\n"; # prints <Hello, Perl!> $x = "Magic, cool stuff!"; print "<$y>\n"; # prints <cool>

        Ah, I think I see (again). So, in the for loop, $_ is an alias to the same memory location as the element in the list being looped over. If that memory location is occupied by something that is semantically an lvalue, then $_ behaves as if it were a C pointer, which is to say, behaves just like the thing it's pointing to. If the memory location is not an lvalue, then $_ does not behave like a C pointer, but still behaves like the thing it's pointing to.
        Is that right?

        I have to stop trying to understand the mechanics of Perl in terms of C.
        <Insert Yoda quote here.>
        So, $_ is imbued with the semantic context of the thing that occupies the memory location to which it points. Still thinking in C, clearly ...

      Yes, except for a precedence problem:

      c:\@Work\Perl\monks>perl -wMstrict -le "my $x = 'abcdefghi'; substr($x, 5, 3) =~ s/g/G/; print $x; " abcdefGhi
      Without some sort of scoping disambiguation, the s/g/G/ binds to 3 in
          substr $x,5,3 =~ s/g/G/;


      Give a man a fish:  <%-{-{-{-<

        Ah, yes, I suspected that might be the case.
        Didn't have access to a command prompt, alas.