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

I've been in deep meditation over this problem for many minutes and now numbly submit the problem to you:

When this block of code is called with a REQUEST_URI of "/" it does not execute listall();

my ($username, $imagename) = $ENV{REQUEST_URI} =~ /\/(.*)\/(.*)/; if(not defined $username || $username eq ""){ listall(); }
However when this block is executed with the same REQUEST_URI, listall(); is executed.
my ($username, $imagename) = $ENV{REQUEST_URI} =~ /\/(.*)\/(.*)/; if(not defined $username){ listall(); }
Why is this? The only thing I can think of is that the order of precedence dictates that the "not" be after the ||.

-caedes

Replies are listed 'Best First'.
Re: When art thy variables defined?
by bronto (Priest) on Jun 22, 2002 at 10:00 UTC

    The problem is actually that || is quite strong (sorry, can't find a better translation from italian), and perl is actually seeing not defined ($username || $username eq ""). To make it work you could just change || with a lower-precedence or. This snippet of code:

    $username = undef ; if (not defined $username || $username eq "") { print "Yep!\n" } if (not defined $username or $username eq "") { print "Yup!\n" }

    prints Yup!.

    Ciao!
    --bronto

Re: When art thy variables defined?
by jepri (Parson) on Jun 22, 2002 at 09:26 UTC
    Update: I thought it was precedence, but now I think it's a function argument vs precednce problem. Solution should still work. Try:

    if((not defined $username) || ($username eq ""))

    Just guessing, but I think perl is seeing:

    if(not defined($username || ($username eq "")))

    It is usually a good idea to explicitly put brackets around everything you want to logically group. Old programmers are religious about this because each language has a different set of operator precedences. After you program in a few, they all mush together and you have no chance of remembering which ones work in the language you are currently programming in.

    ____________________
    Jeremy
    I didn't believe in evil until I dated it.

Re: When art thy variables defined?
by abstracts (Hermit) on Jun 22, 2002 at 10:32 UTC
    Are you sure this is what you want?
    my ($username, $imagename) = $ENV{REQUEST_URI} =~ /\/(.*)\/(.*)/;
    The reason I'm asking is because you need to consider the following input possibilities:
    ""
    "/"
    "//"
    "///"
    "/a/b"
    "/a/b/"
    "/a/b/c"
    "/a/b/c/"
    "a//"
    "a/b/"
    ...
    
    You see, your regex would match any string with 2 or more slashes no matter where they occur. Also, you have a greedy * which will match the longest string.

    Example: "/a/b/c/d/e" => $user = "a/b/c/d", $img = "e" which may not be what you want.

    You may need to put more constraints on the check. I think the regex you're looking for is in the neighbourhood of:

    my ($user, $img) = $ENV{REQUEST_URI} =~ m#^/([^/]+)/([^/]+)$#;
    It may look more complex than your original regex, but should do the job. Of course, look at perlre for all the details.

    Hope this helps,,,

    Update: If you're using $user as a directory name, beware of people passing it "/../something" as that would open a door for people to access other information.

Re: When art thy variables defined?
by Aristotle (Chancellor) on Jun 22, 2002 at 15:57 UTC
    When in doubt, Deparse. In this case we want extra -parentheses.
    $ perl -MO=Deparse,-p -e'if(not defined $username || $username eq ""){ +}' if ((not (defined($username) || ($username eq '')))) { (); } -e syntax OK

    Apparently noone's gut feeling was entirely correct - mine neither. Don't try guessing.

    Makeshifts last the longest.

Re: When art thy variables defined?
by particle (Vicar) on Jun 22, 2002 at 10:44 UTC
    jepri and bronto have covered this subject well... but nobody's pointed to the documentation yet! see perlop for more on operators and precedence rules.

    ~Particle *accelerates*