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

Hello, I am trying to the following in a perl script:
open(FILE,$license) || die ("Could not open the file\n"); @file=<FILE>; $find="license @abc"; foreach $line (@file){ if ($line =~/$find/) { print "Found!!!!!!\n"; print "$line\n"; } }
It gives me the error: Use of uninitialized value in pattern match (m//). What am I missing here? Thanks in advance.

Replies are listed 'Best First'.
Re: Unable to find a pattern
by GrandFather (Saint) on Jun 10, 2008 at 23:31 UTC

    There are a number of things you ought to tidy up in your code. First off, always use strictures (use strict; use warnings;).

    Use the three parameter version of open.

    Avoid slurping files (@file=<FILE>;).

    Use a precompiled regex instead of interpolating a string into a regex.

    Early exits and statement modifiers work very well to eliminate excessive indentation (see next unless $_ =~ $find; below).

    Multiple ! marks are a sure sign of a demented mind (although that may not be a programming tip). :-)

    Consider the following reworked example:

    use strict; use warnings; my $license = 'Wibble'; open FILE, '<', $license || die ("Could not open the file\n"); my $find = qr'license @abc'; while (<FILE>) { next unless $_ =~ $find; print "Found!\n"; print "$_\n"; }

    Perl is environmentally friendly - it saves trees
Re: Unable to find a pattern
by massa (Hermit) on Jun 10, 2008 at 22:28 UTC
    either use single quotes or put a backslash before the @ because it's trying to interpolate the inexistent var @abc in your pattern string.
Re: Unable to find a pattern
by ww (Archbishop) on Jun 11, 2008 at 01:53 UTC

    Re GrandFather's ( ++ )

    my $find = qr'license @abc';

    versus

    my $find = qr/license \@abc/;

    see perldoc perlop at " Quote and Quote-like Operators" re the quoting ( ww added notes marked by "<!--"):

    While we usually think of quotes as literal values, in Perl they function as operators, providing various kinds of interpolating and pattern matching capabilities. Perl provides customary quote characters for these behaviors, but also provides a way for you to choose your quote character for any of them. In the following table, a "{}" represents any pair of delimiters you choose.
    Customary  Generic        Meaning        Interpolates
         ''       q{}          Literal             no
         ""      qq{}          Literal             yes
         ``      qx{}          Command             yes*
                 qw{}         Word list            no
         //       m{}       Pattern match          yes*
                 qr{}          Pattern             yes*     <!-- backslash is required 
                                                                 if using /.../ 
                 s{}{}       Substitution          yes* 
         ....
         * unless the delimiter is ''.                      <!-- NB!
    

    In other words, if you chose to use my $find = qr/license \@abc/;, the escaping backwhack is required (as massa advised AND as you would have learned had you used the strictures recommended above).