why warn on undefined $1?

Discussion in 'Perl Misc' started by ihok@hotmail.com, Aug 29, 2007.

  1. Guest

    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.
    , Aug 29, 2007
    #1
    1. Advertising

  2. Guest

    "" <> wrote:
    > 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

    --
    -------------------- http://NewsReader.Com/ --------------------
    Usenet Newsgroup Service $9.95/Month 30GB
    , Aug 29, 2007
    #2
    1. Advertising

  3. Mirco Wahab Guest

    wrote:
    > 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.
    Mirco Wahab, Aug 29, 2007
    #3
  4. Guest

    On Aug 29, 5:01 pm, wrote:
    >
    > 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!
    , Aug 29, 2007
    #4
  5. Ben Morrow Guest

    Quoth :
    > "" <> wrote:
    > > 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/


    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
    Ben Morrow, Aug 30, 2007
    #5
  6. Guest

    On Aug 29, 7:01 pm, Ben Morrow <> wrote:
    > 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
    , Aug 30, 2007
    #6
  7. wrote:
    > 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";

    > print $s;
    > # coloured


    --
    Gunnar Hjalmarsson
    Email: http://www.gunnar.cc/cgi-bin/contact.pl
    Gunnar Hjalmarsson, Aug 30, 2007
    #7
  8. Guest

    On Aug 29, 7:33 pm, Gunnar Hjalmarsson <> wrote:
    > wrote:
    > > 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";
    >
    > > print $s;
    > > # coloured


    Awesome. Is there any way to precompile the $re, as qr// would do?
    , Aug 30, 2007
    #8
  9. wrote:
    > On Aug 29, 7:33 pm, Gunnar Hjalmarsson <> wrote:
    >> wrote:
    >>> 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";
    >>
    >>> print $s;
    >>> # coloured

    >
    > 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/;

    --
    Gunnar Hjalmarsson
    Email: http://www.gunnar.cc/cgi-bin/contact.pl
    Gunnar Hjalmarsson, Aug 30, 2007
    #9
  10. On Aug 29, 1:49 pm, "" <> wrote:
    > 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/;

    --
    Charles DeRykus
    comp.llang.perl.moderated, Aug 30, 2007
    #10
  11. Dr.Ruud Guest

    schreef:
    > Ben Morrow:
    >> 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.


    $str =~ s{ (?<= colo) (?= r(?: ed|ing|s|) \b) }
    {u}gx;

    --
    Affijn, Ruud

    "Gewoon is een tijger."
    Dr.Ruud, Aug 30, 2007
    #11
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Mr. SweatyFinger

    why why why why why

    Mr. SweatyFinger, Nov 28, 2006, in forum: ASP .Net
    Replies:
    4
    Views:
    880
    Mark Rae
    Dec 21, 2006
  2. Mr. SweatyFinger
    Replies:
    2
    Views:
    1,849
    Smokey Grindel
    Dec 2, 2006
  3. Cuthbert
    Replies:
    89
    Views:
    1,325
    Michael Wojcik
    Sep 11, 2006
  4. Iñaki Baz Castillo

    Why does "warn" print a extra \n ?

    Iñaki Baz Castillo, Jan 4, 2010, in forum: Ruby
    Replies:
    3
    Views:
    93
    Xavier Noria
    Jan 5, 2010
  5. Sara
    Replies:
    0
    Views:
    99
Loading...

Share This Page