moving a match into a subroutine

S

Stefan Ram

I want to have the match »something =~ /(.)/g« to be kept in a
separate subroutine, because then, I can keep this at the
start of my script. (I like to collect those parts of my
script that I change often there.)

However, as one can see from the script below, my first attempt
(exhibit 0) does not work, it only prints empty lines.

When I do not use a subroutine (exhibit 1), the behavior is as
wanted: it prints lines with »a«, »b«, and »c«.

Can I put the match »something =~ /(.)/g« in a separate
source code entity that can be moved to the top of my script
(like a subroutine) and still get the behavior of exhibit 1?

#!/usr/bin/perl
#perl 5.8.3

use strict;
use warnings;

my $text = "abc";

# exhibit 0
sub match($){ $_[0] =~ /(.)/g }
while( match( $text ))
{ print $1, "\n"; }

# exhibit 1
while( $text =~ /(.)/g )
{ print $1, "\n"; }
 
C

C.DeRykus

  I want to have the match »something =~ /(.)/g« to be kept in a
  separate subroutine, because then, I can keep this at the
  start of my script. (I like to collect those parts of my
  script that I change often there.)

  However, as one can see from the script below, my first attempt
  (exhibit 0) does not work, it only prints empty lines.


  When I do not use a subroutine (exhibit 1), the behavior is as
  wanted: it prints lines with »a«, »b«, and »c«.

  Can I put the match »something =~ /(.)/g« in a separate
  source code entity that can be moved to the top of my script
  (like a subroutine) and still get the behavior of exhibit 1?

#!/usr/bin/perl
#perl 5.8.3

use strict;
use warnings;

my $text = "abc";

# exhibit 0
sub match($){ $_[0] =~ /(.)/g }
while( match( $text ))
{ print $1, "\n"; }


Backreferences are dynamically scoped within the local block
so, in this case, $1 is undefined outside your subroutine
block. You should also see the helpful warning:

Use of uninitialized value $1 in concatenation (.) ...

One way to correct the problem:

sub match { return $_[0] =~ /(.)/g ? $1 : undef; }
while( my $matched = match( $text )){ print "$matched\n"; }
 
E

Eric Pozharski

On 2009-07-16 said:
However, as one can see from the script below, my first attempt
(exhibit 0) does not work, it only prints empty lines.

Did you run it? Besides you didn't copy-paste.

*SKIP*
#!/usr/bin/perl
#perl 5.8.3

use strict;
use warnings;

my $text = "abc";

# exhibit 0
sub match($){ $_[0] =~ /(.)/g }
while( match( $text ))
{ print $1, "\n"; }

print "$_\n" for match $text;

That's your fish.
 
S

sln

I want to have the match »something =~ /(.)/g« to be kept in a
separate subroutine, because then, I can keep this at the
start of my script. (I like to collect those parts of my
script that I change often there.)

However, as one can see from the script below, my first attempt
(exhibit 0) does not work, it only prints empty lines.

When I do not use a subroutine (exhibit 1), the behavior is as
wanted: it prints lines with »a«, »b«, and »c«.

Can I put the match »something =~ /(.)/g« in a separate
source code entity that can be moved to the top of my script
(like a subroutine) and still get the behavior of exhibit 1?

#!/usr/bin/perl
#perl 5.8.3

use strict;
use warnings;

my $text = "abc";

# exhibit 0
sub match($){ $_[0] =~ /(.)/g }
while( match( $text ))
{ print $1, "\n"; }

# exhibit 1
while( $text =~ /(.)/g )
{ print $1, "\n"; }

The other posters pointed out your problem.
Probably thier two solutions can be combined into 1.

------------------------------
use strict;
use warnings;

my $text = "abc";
my $val;

sub match($) {
return $_[0] =~ /./g if wantarray;
$_[0] =~ /(.)/g;
$1; # <-- goes out of scope here, just return its value
}

# Scalar context, multiple match() calls
print "$val\n" while ( $val = match( $text ));

print '-' x 20, "\n"; # pos($text) is reset after failed match (unless \G)

# List context, single match() call
print "$_\n" for ( match( $text ));
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,969
Messages
2,570,161
Members
46,710
Latest member
bernietqt

Latest Threads

Top