why warn on undefined $1?

I

ihok

Consider:

# colors -> colours
$token = 'colors';
$token =~ s/or(ed|ing|s)?$/our$1/;

But if $token == 'color', Perl emits a warning: Use of uninitialized
value in concatenation (.) or string. True enough, $1 is undefined,
but why bother warning? I mean, my regexp has a '?' in it because I
expect that sometimes 'color' will not have an ending.

I suspect that the answer is "it's simpler to just warn whenever an
undefined variable occurs in a string, and it's just not worth it to
detect the case when such a warning is vacuous. Try 'no warnings'.' I
can deal with that.
 
X

xhoster

Consider:

# colors -> colours
$token = 'colors';
$token =~ s/or(ed|ing|s)?$/our$1/;

But if $token == 'color', Perl emits a warning: Use of uninitialized
value in concatenation (.) or string. True enough, $1 is undefined,
but why bother warning? I mean, my regexp has a '?' in it because I
expect that sometimes 'color' will not have an ending.

There are limits to DWIM. Perl doesn't know why you stuck the ? in, so
it can't tailor its behavior to this unknown motivation.
I suspect that the answer is "it's simpler to just warn whenever an
undefined variable occurs in a string, and it's just not worth it to
detect the case when such a warning is vacuous. Try 'no warnings'.' I
can deal with that.

You can do that, but I think it would make more sense to change your regex
to explicitly let it match and capture the empty string:

s/or(ed|ing|s|)$/our$1/

Xho
 
M

Mirco Wahab

Consider:

# colors -> colours
$token = 'colors';
$token =~ s/or(ed|ing|s)?$/our$1/;

But if $token == 'color', Perl emits a warning: Use of uninitialized
value in concatenation (.) or string. True enough, $1 is undefined,
but why bother warning? I mean, my regexp has a '?' in it because I
expect that sometimes 'color' will not have an ending.

xhoster did already point to a solution,
but you could also be more explicit about
your search term, e.g.

my $token = 'color';
$token =~ s/ \B or(ed | ing | s | $)? /our$1/x;

by simply putting the $ (or a \b) into the
capturing parenthesis. I added another \B
in front of the term in order to make
clear that we start the search in the
middle of a word.
 
I

ihok

You can do that, but I think it would make more sense to change your regex
to explicitly let it match and capture the empty string:

s/or(ed|ing|s|)$/our$1/

Bingo! I didn't know you could do that. Thanks!
 
B

Ben Morrow

Quoth (e-mail address removed):
There are limits to DWIM. Perl doesn't know why you stuck the ? in, so
it can't tailor its behavior to this unknown motivation.


You can do that, but I think it would make more sense to change your regex
to explicitly let it match and capture the empty string:

s/or(ed|ing|s|)$/our$1/

Or (better IMHO), use look-around assertions:

my $str = 'color colored tricolor floor';
$str =~ s/ (?<= col) or (?= (?: ed|ing|s)? \b) /our/gx;
print $str;
# colour coloured tricolour floor

Ben
 
I

ihok

Or (better IMHO), use look-around assertions:

my $str = 'color colored tricolor floor';
$str =~ s/ (?<= col) or (?= (?: ed|ing|s)? \b) /our/gx;
print $str;
# colour coloured tricolour floor

Whoa. That's heavy.

Next question: how can I store the s/// regexp in a variable? I want
something like qr//, but for s///. In other words, I want this to
work, but it doesn't.

my $re = s/or(ed|ing|s)?$/our$1/;
my $s = 'colored';
$s =~ $re;
print $s;
# coloured
 
G

Gunnar Hjalmarsson

how can I store the s/// regexp in a variable? I want
something like qr//, but for s///. In other words, I want this to
work, but it doesn't.

my $re = s/or(ed|ing|s)?$/our$1/;

my $re = 's/or(ed|ing|s)?$/our$1/';
my $s = 'colored';
$s =~ $re;

eval "\$s =~ $re";
 
G

Gunnar Hjalmarsson

Awesome. Is there any way to precompile the $re, as qr// would do?

This is all I can think of:

my $re = qr/or(ed|ing|s)?$/;
my $s = 'colored';
$s =~ s/$re/our$1/;
 
C

comp.llang.perl.moderated

Consider:

# colors -> colours
$token = 'colors';
$token =~ s/or(ed|ing|s)?$/our$1/;

But if $token == 'color', Perl emits a warning: Use of uninitialized
value in concatenation (.) or string. True enough, $1 is undefined,
but why bother warning? I mean, my regexp has a '?' in it because I
expect that sometimes 'color' will not have an ending.

I suspect that the answer is "it's simpler to just warn whenever an
undefined variable occurs in a string, and it's just not worth it to
detect the case when such a warning is vacuous. Try 'no warnings'.' I
can deal with that.

You could add an empty alternative to cause
$1 to match an empty string thus preventing
a warning:

$token =~ s/or(ed|ing|s|)?$/our$1/;
 

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

Forum statistics

Threads
474,266
Messages
2,571,079
Members
48,772
Latest member
Backspace Studios

Latest Threads

Top