On 2006.4.5, at 09:36 AM, Doug McNutt wrote:

While messing with CGI POSTed data I got trapped by this one.

Version 5.8.1-RC3 for Mac OS 10.3.9

It appears that the hash element "D" gets defined in the process of testing to see if an element in the associated string is defined. The last if below takes the else route.

Is that normal? Does it somehow make sense?

%phash = ();
foreach $jill ("A", "B", "C")
    {
    for ($lynn = 0; $lynn<3; $lynn++)
        {
        $phash{$jill}[$lynn] = "$jill$lynn";
        print "\$phash{$jill}[$lynn] = $phash{$jill}[$lynn]\n";
        }
    }
if (! defined $phash{"D"})
    {
    print "\$phash{D} is undefined, We expected that.\n";
    }

I should run the code before hazarding guesses, but I'm guessing you find it is not defined above,

if (! defined $phash{"D"}[3])
    {
    print "\$phash{D}[3] is undefined. We expected that too.\n";
    }

... but defined after this one is done, So that the above two would show "is undefined", but the next would show "got defined."

The reason I would guess this is that perl does automagically define things in a lot of cases where other languages (like java) would throw fits, I mean, throw exceptions. Perl is designed from the point of view that the programmer thought he knew what he was doing, which, from a purely mathematical point of view, is dangerous, but in the real world is often the desired path.

Leaving the deep philosophy aside, if $phash{"D") is not defined, there are three or four ways to parse $phash{"D"}[3]. The java way would be (I think) to throw the conniption, I mean, exception: Can't access an array off a null pointer. Another way might be to short-circuit the test, if $phash{"D"} is not defined, no way can anything referenced off it be defined. But that path requires intelligence which we have not yet been able to give programming languages and expect them to completely parse any program in anything approaching determinant time. {Oh. Wait. One more path I gotta check before I call this either valid or invalid. Oh, wait, ...}

So perl simply defines the thing so that the rest of the test can complete, as I understand it.

if (! defined $phash{"D"})
    {
    print "\$phash{D} is undefined\n";
    }
else
    {
    print "\$phash{D} got defined - why?\n";
    }
__END__

--

Applescript syntax is like English spelling:
Roughly, but not thoroughly, thought through.

Yeah, and Applescript does a bit more than perl on the trying to read the programmer's mind, but it was a really bizarre programmer's mind it was trained, I mean programmed to read.

8-*

Reply via email to