Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

Re: scoping problem?

by rocroc (Initiate)
on Dec 06, 2011 at 20:26 UTC ( #942100=note: print w/ replies, xml ) Need Help??


in reply to scoping problem?

Ok, so first of all, thanks AnomolousMonk. The text file did have a blank line at the end. This means that my initial understanding of the problem was wrong: I had thought that $username was being interpolated like I expected in the matching expression but not in the print statement.

Now, indeed, when that blank line is read, the match is successful, and so the print get's called, but the variable $username is empty. This means that $username is failing to be interpolated in BOTH the match AND the call to print.

But that is not the whole story. Here's a slightly modified script: (the #NEW comment marks the one line I've added to the original):

use strict; my $username; my $color; while(<>){ chomp; s/"//g; ($username,$color) = (split /,/,$_)[2,3]; print STDOUT "$username\n"; #NEW if ("agag" =~ m/($username)/){print STDOUT "here is the username: +$username\n"} }
when I run this with the same invocation as before (perl test.pl test.txt), here's the output I get (and by the way, the text file still ends with a blank line):
adad agag ahah here is the username:

Wierd, huh? The $username comes out as expected when used in the "naked" print statement (the line marked #NEW), but it fails to be interpolated in BOTH the match AND the print statement in the following line.

OK, now a second point here. (it get's wierder!) Corion tests the script by "hard coding" the data from the text file into the script like so:
use strict; my $username; my $color; while(<DATA>){ chomp; s/"//g; ($username,$color) = (split /,/,$_)[2,3]; if ("agag" =~ m/($username)/){ print STDOUT "here is the username: $username\n" } } __DATA__ "ADELMAN","John","adad","Ray" "AGAN","John","agag","Aditya" "AHMED","John","ahah","Conor"
Now, when I run this on my machine, I get the output I'm looking for -- i.e.
here is the username: agag
So, I'm still stumped. Is this a scoping problem (like $username goes out of scope when we get into the "if" statement)? Is there something I don't understand about the diamond operator (that's what Corion's finding suggests to me)? Could this be some sort of file permission issue (I'm running linux, and working in the shell as a regular user. and no, I'm not willing to run this script as root).


Comment on Re: scoping problem?
Select or Download Code
Re^2: scoping problem?
by chromatic (Archbishop) on Dec 06, 2011 at 21:09 UTC

    How do you know the result of split gives you (at least) four items? Add a diagnostic print to show you $_ and you'll probably see what's happening.

    It's not a scoping problem or a readline problem or a permission problem.


    Improve your skills with Modern Perl: the free book.

      Thanks chromatic. Here's the script with additional tests to see what's in $_. at each point.
      use strict; use warnings; my $username; my $color; while(<>){ chomp; s/"//g; ($username,$color) = (split /,/,$_)[2,3]; print STDOUT "test of username: $username\n";#NEW print STDOUT "test of dollar-underscore: $_\n";#NEW ALSO if ("agag" =~ m/($username)/){ print STDOUT "here is the username: $username\n"; print STDOUT "here is dollar-underscore: $_\n"; } }
      here's the output of 'perl test.pl test.txt' (script includes "use warnings" this time, so they are included in the output)
      test of username: adad test of dollar-underscore: ADELMAN,John,adad,Ray test of username: agag test of dollar-underscore: AGAN,John,agag,Aditya test of username: ahah test of dollar-underscore: AHMED,John,ahah,Conor Use of uninitialized value $username in concatenation (.) or string at + test.pl line 11, <> line 4. test of username: test of dollar-underscore: Use of uninitialized value $username in regexp compilation at test.pl +line 13, <> line 4. Use of uninitialized value $username in concatenation (.) or string at + test.pl line 14, <> line 4. here is the username: here is dollar-underscore:

      Note that $_ and $username are both coming out as they should (i.e. the split is working) before we get to the if statement. It just looks as though the match "agag" =~ m/($username)/ is failing. (note that the warnings are only being issued at the fourth "line" of the text file -- that is at the empty last line.)

      still stumped. Perhaps I'm missing something really basic and obvious about the match operator?

        Realy strange. Works for me:
        test of username: agag test of dollar-underscore: AGAN,John,agag,Aditya here is the username: agag here is dollar-underscore: AGAN,John,agag,Aditya
        Are you sure your input does not contain any non-printable characters?

        My results are similar to choroba's. I suspect rocroc is being a bit coy with us about the code or data actually being used because I don't get the same output from the the posted code of Re^3: scoping problem?. I am using a  data file with the OPed data plus a blank line at the end.

        I have made minor code changes as follows:

        1. The substitution  s/"//g; is changed to  s/\x22//g; (0x22 is the hex value of ASCII " (double-quote)) because my little command-line editor gets very confused by unbalanced double-quotes.
        2. I have added single-quotes around the variables in the diagnostic print statements to clearly delineate the strings being printed.

        As you can see, the 'agag' record is detected (as well as the blank line, of course).

        >perl -wMstrict -le "my $username; my $color; while(<>){ chomp; s/\x22//g; ($username,$color) = (split /,/,$_)[2,3]; print STDOUT \"test of username: '$username'\n\"; print STDOUT \"test of dollar-underscore: '$_'\n\"; if (\"agag\" =~ m/($username)/){ print STDOUT \"here is the username: '$username'\n\"; print STDOUT \"here is dollar-underscore: '$_'\n\"; } } " data test of username: 'adad' test of dollar-underscore: 'ADELMAN,John,adad,Ray' test of username: 'agag' test of dollar-underscore: 'AGAN,John,agag,Aditya' here is the username: 'agag' here is dollar-underscore: 'AGAN,John,agag,Aditya' test of username: 'ahah' test of dollar-underscore: 'AHMED,John,ahah,Conor' Use of uninitialized value $username in concatenation (.) or string at + -e line 1, <> line 4. test of username: '' test of dollar-underscore: ' ' Use of uninitialized value $username in regexp compilation at -e line +1, <> line 4. Use of uninitialized value $username in concatenation (.) or string at + -e line 1, <> line 4. here is the username: '' here is dollar-underscore: ' '
Re^2: scoping problem?
by GrandFather (Cardinal) on Dec 07, 2011 at 00:23 UTC

    I suspect you are still falling foul of blank lines or maybe unexpected line endings (Windows cr/lf line endings on a *nix system for example). The following code may be closer to what you need:

    use strict; use warnings; open my $tempOut, '>', 'delme.txt' or die "Can't create temp file: $!\ +n"; print $tempOut <<FILE; "ADELMAN","John","adad","Ray" "AGAN","John","agag","Aditya" "AHMED","John","ahah","Conor" FILE close $tempOut; @ARGV = 'delme.txt'; while(<>){ chomp; s/"//g; my ($username,$color) = (split /,/,$_)[2,3]; next if ! defined $color; print "here is the username: $username\n" if "agag" =~ m/($usernam +e)/; }

    Prints:

    here is the username: agag

    However you seem to be parsing a CSV file so really you should be using one of the modules designed for that task such as Text::CSV.

    Oh, and you really should use warnings in addition to strict!

    True laziness is hard work
Re^2: scoping problem?
by AnomalousMonk (Monsignor) on Dec 07, 2011 at 10:06 UTC
    ... thanks AnomolousMonk. The text file did have a blank line at the end.

    keszler suggested that. I just supplied a long-winded example of the effects.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://942100]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others wandering the Monastery: (9)
As of 2014-08-22 08:57 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The best computer themed movie is:











    Results (151 votes), past polls