skamalakannan has asked for the wisdom of the Perl Monks concerning the following question:

I get a message uninitialisation value. What is wrong in this program

#! /usr/bin/perl -w use strict; my $a = <STDIN>; $a =~ (m/\d\d\.\d\d/) || (m/\$\d\d\d\.\d\d\d/) || (m/\$\.\d\d/); print "$a is true";

Kamalakannan.

20051124 Janitored by Corion: Added formatting

Replies are listed 'Best First'.
Re: What is wrong in this
by EvanCarroll (Chaplain) on Nov 24, 2005 at 08:49 UTC
    What you have means this:
    $a =~ (m/\d\d\.\d\d/) || $_ =~ (m/\$\d\d\d\.\d\d\d/) || $_ =~ (m/\$\.\ +d\d/);


    When you want this:
    chomp $a; $a =~ (m/\d\d\.\d\d/) || $a =~ (m/\$\d\d\d\.\d\d\d/) || $a =~ (m/\$\.\ +d\d/);
    Don't forget to chomp! Prior to the opperation, or you will have your newline input record seperater ($/) at the end of your line.

    Update:
    I should also mention using $a, and $b, is bad, they are variables that should be reserved for sort, and golf.

    Update:
    And, while I'm at it use quantifiers and do something like this:
    chomp $a; $a =~ (m/\d{2,3}.\d{2,3}/) || $a =~ (m/\$\d{3}.\d\{2}/) || $a =~ (m/\$ +\.\d{2}/);

    Which matches ##.##, $###.### and $.##, If you wanted $##.## however you could do something this:
    m/\$?(?:\d{2,3})?\.\d{2}/ which looks alot like a crummy money regex, and your probably better off going to cpan for that.


    Evan Carroll
    www.EvanCarroll.com
Re: What is wrong in this
by Perl Mouse (Chaplain) on Nov 24, 2005 at 09:31 UTC
    You probably want:
    $a =~ /\d\d\.\d\d/ || $a =~ /\$\d\d\d\.\d\d\d/ || $a =~ /\$\.\d\d/
    But there's more to say. Note that the second condition can only be true of the first condition is true, so there is no point of having the second condition. Which leaves:
    $a =~ /\d\d\.\d\d/ || $a =~ /\$\.\d\d/;
    You could combine the two regexes into:
    $a =~ /(?:\d\d|\$)\.\d\d/;
    but I'm not sure whether that's faster; and whether it's clearer and easier to maintain is debatable.
    Perl --((8:>*
Re: What is wrong in this
by Anonymous Monk on Nov 24, 2005 at 08:52 UTC

    or :

    $a =~ m/\d\d\.\d\d||\$\d\d\d\.\d\d\d||\$\.\d\d/;

      Alternations in regexen are a single pipe, not a double pipe. Your version has two null alternations, and will thus match the empty string, and since it isn't anchored, anything:

      $ perl -le 'print "foo" if "zoombots" =~ m/baz||bar/' foo
A reply falls below the community's threshold of quality. You may see it by logging in.