http://qs321.pair.com?node_id=11120209


in reply to Split fake, an emulation of split

To address one question:

...limitations on what can be an argument to Regexp Quote Like Operators

# while ( my $rv = $$str_ref =~ m{$pat_re}gc ) { does not work

But it does. All tests in the suite pass OK with this line restored. You probably used the same scalar variable with other (not shown) tests in succession, and the (useless here) "c" modifier had left this scalar's pos property being set after the very 1st splitF call, then further calls produced bogus results. So, the bad (or good?) news is, there is no undocumented limitation, but the really good news -- in this case, I think -- if you had omitted "c" but wrote line as above, all tests (shown or not) would pass OK. And yet, such implementation would lead to subtle and evil bugs: the pos of referent (splitF argument, as opposed to disposable lexical copy) would be: (a) reset, and, maybe worse, (b) taken into account if it had been set previously to splitF call.

Replies are listed 'Best First'.
Re^2: Split fake, an emulation of split
by bojinlund (Monsignor) on Aug 03, 2020 at 18:55 UTC

    Thanks vr for the answer!

    Your answer has made me understand why, I several times "found" limitations, on what can be an argument to Regexp Quote Like Operators.

    The (useless here) "c" modifier in combination with other errors have fooled me. I have also erroneously thought that the string used in $str =~ m{$pat} could not change during the match.

    The error message "Use of uninitialized value in pattern match (m//)" has made me believe that the input was the problem. Not the value after one or more matches.

    use strict; use warnings; use 5.010; use Data::Dump qw(dump dd ddx); use Test::More; sub match { # $pat, $str_ref warn "\nmatch", dump @_; my $pat = $_[0]; my $str_ref = $_[1]; my @res; say STDERR '$str_ref before loop: ', dump $str_ref; while ( my $rv = $$str_ref =~ m{$pat}g ) { say STDERR 'in loop: ', dump $str_ref, $rv, @{^CAPTURE}; push @res, @{^CAPTURE}; } say STDERR 'match: ', ( dump @res ), "\n"; return @res; } sub spliT { # $pat, $str_ref warn "\nspliT", dump @_; my @rv = split $_[0], ${ $_[1] }; say STDERR 'split: ', ( dump @rv ), "\n"; return @rv; } $_ = 'ERROR?'; /(.+)/; # set $1 my $match_OK = [ ':', ':' ]; my $split_OK = [ "a", ":", "b", ":", "c" ]; is_deeply [ match( qr{(:)}, \'a:b:c' ) ], [ ':', ':' ], q{\'a:b:c'}; my $dollar1_ref; { my $str = 'a:b:c'; $_ = $str; /(.+)/; $dollar1_ref = \$1; warn "\n\$dollar1_ref: ", dump $dollar1_ref; is_deeply [ match( qr{(:)}, $dollar1_ref ) ], $match_OK, q{$dollar +1_ref}; warn "NOK because \$\$dollar1_ref is changed by m{}\n"; warn "\n\$dollar1_ref: ", dump $dollar1_ref; is_deeply [ spliT( qr{(:)}, $dollar1_ref ) ], $split_OK, q{spliT( qr{(:)}, $dollar1_ref)}; warn "\n\$dollar1_ref: ", dump $dollar1_ref; warn "\n ===== leave scope"; } warn "\n\$dollar1_ref: ", dump $dollar1_ref; # $dollar1_ref = \undef # is_deeply [ match( qr{(:)}, $dollar1_ref ) ], $match_OK, q{$dollar1_ +ref}; # is_deeply [ spliT( qr{(:)}, $dollar1_ref ) ], $split_OK, # q{spliT( qr{(:)}, $dollar1_ref}; done_testing(); __DATA__ output: match(qr/(:)/, \"a:b:c") at pm_5.pl line 17. $str_ref before loop: \"a:b:c" in loop: (\"a:b:c", 1, ":") in loop: (\"a:b:c", 1, ":") match: (":", ":") ok 1 - \'a:b:c' $dollar1_ref: \"a:b:c" at pm_5.pl line 51. match(qr/(:)/, \"a:b:c") at pm_5.pl line 17. $str_ref before loop: \"a:b:c" in loop: (\":", 1, ":") match: ":" not ok 2 - $dollar1_ref # Failed test '$dollar1_ref' # at pm_5.pl line 53. # Structures begin differing at: # $got->[1] = Does not exist # $expected->[1] = ':' NOK because $$dollar1_ref is changed by m{} $dollar1_ref: \"a:b:c" at pm_5.pl line 56. spliT(qr/(:)/, \"a:b:c") at pm_5.pl line 31. split: ("a", ":", "b", ":", "c") ok 3 - spliT( qr{(:)}, $dollar1_ref) $dollar1_ref: \"a:b:c" at pm_5.pl line 60. ===== leave scope at pm_5.pl line 61. $dollar1_ref: \"ERROR?" at pm_5.pl line 64. 1..3 # Looks like you failed 1 test of 3.

    I am a little bit surprised that split could handle split $_[0], ${ $_[1] };

    Thank you very much!!