louie@sayshell.umd.edu (Louis A. Mamakos) (08/13/90)
I noticed that a perl script that I had stopped working under patchlevel 27. It seems like the defined() operator is working differently than it did before. try this out: #!/usr/local/bin/perl if (defined(@foo)) { print "defined\n"; } else { print "not defined\n"; } undef @foo; if (defined(@foo)) { print "defined\n"; } else { print "not defined\n"; } __END__ and you'll get defined not defined printed at you. Patchlevel 18 gives not defined not defined This is on a NeXT workstation, and all tests passed just fine. louie
raymond@math.berkeley.edu (Raymond Chen) (11/08/90)
[The question:] Consider the following script: @foo{"bar"} = (); print keys(%foo), "\n"; # See, it's listed as one of the keys if (defined($foo{"bar"})) { print "Patch level 18 prints this\n"; } else { print "Patch level 36 prints this\n"; } Observe that $foo{"bar"} was created via an associative array slice. Who is right, Patch level 18 or Patch level 36? The problem seems to be that, although $foo{"bar"} is defined, its value is undef. This schizophrenic state of affairs seems to lead to different interpretations depending on your patch level. (Maybe because PL16 initialized $foo{"bar"} = ""? Is this related to the change in semantics of local()?) [How I noticed this:] My current code initializes a list of commands via @commands{ split(/ /, "Scale Height Width Borders etc...") } = (); and tests if a particular token is a command via if (defined($commands{$token})) {...} This breaks under PL36 as described above. I know I can write for (split(/ /, "Scale Height Width etc...")) { $commands{$_} = 1; } but somehow, the slice looked spiffier to me at the time. Ah, the price one pays for a moment of folly. -- @japh{split(/:/, "hacker,:Just :erl :another p")} = (); print sort keys %japh; # Extra credit: What is $japh{"hacker,"}? What is defined($japh{"hacker,"})?
lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) (11/13/90)
In article <1990Nov8.005449.26158@agate.berkeley.edu> raymond@math.berkeley.edu writes: : [The question:] : : Consider the following script: : : @foo{"bar"} = (); : print keys(%foo), "\n"; # See, it's listed as one of the keys : if (defined($foo{"bar"})) { print "Patch level 18 prints this\n"; } : else { print "Patch level 36 prints this\n"; } : : Observe that $foo{"bar"} was created via an associative array slice. : : Who is right, Patch level 18 or Patch level 36? It's a judgement call, but I think 36 is righter. It's nice to be able to differentiate @foo{"bar"} = (); from @foo{"bar"} = (""); Or look at it another way. You can have an existing variable with an undefined value, why not an existing array element with an undefined value? If the x operator worked on array values (it doesn't), then you could say @foo{"foo", "bar"} = (1) x 2; (I don't think I can make x work on array values without breaking scripts, alas. Hmm, maybe I can, if I require the parens. Hmm... Still possible to break scripts, I think...) : The problem seems to be that, although $foo{"bar"} is defined, : its value is undef. This schizophrenic state of affairs seems to : lead to different interpretations depending on your patch level. : : (Maybe because PL16 initialized $foo{"bar"} = ""? Is this related : to the change in semantics of local()?) Yes, it is. It's actually a difference in the semantics of list assignment, of which local() assignment is a subset. : [How I noticed this:] : : My current code initializes a list of commands via : : @commands{ split(/ /, "Scale Height Width Borders etc...") } = (); : : and tests if a particular token is a command via : : if (defined($commands{$token})) {...} : : This breaks under PL36 as described above. : : I know I can write : : for (split(/ /, "Scale Height Width etc...")) { $commands{$_} = 1; } : : but somehow, the slice looked spiffier to me at the time. Ah, the : price one pays for a moment of folly. How 'bout something like this: %commands = &set("Scale Height Width Borders etc..."); sub set { local($string, @result) = @_; for (split(' ', $string)) { push(@result, $_, 1); } @result; } if ($commands{$token}) {...} It would be nice if there was a way to generate arbitrarily long lists of some specified value on demand, but I haven't (yet) got up the gumption to turn Perl into Icon. :-) Larry
friedman@chekov.UU.NET (Barry Friedman) (03/21/91)
I've noticed the following non-intuitive behaviour of 'defined()': When a variable is used in a string it becomes defined. I don't recall any discussion on this. #!/usr/bin/perl $a='$b is undefined'; $a='$b is defined' if defined ($b); print $a,"\n"; print "b is now <$b>","\n"; $a='$b is defined' if defined ($b); print $a,"\n"; __END__ produces $b is undefined b is now <> $b is defined -- Barry Friedman INTERNET: friedman%chekov@uunet.uu.net Phone: (613) 782-2389 UUCP: ...!uunet!chekov!friedman Emax Computer Systems Inc. 440 Laurier Ave. W., Ottawa, Ont. Canada K1R 5C4
composer@chem.bu.edu (Jeff Kellem) (03/22/91)
In article <1991Mar21.142935.11333@bmers145.bnr.ca> friedman@chekov.UU.NET (Barry Friedman) writes: > I've noticed the following non-intuitive behaviour of 'defined()': > When a variable is used in a string it becomes defined. > > I don't recall any discussion on this. > > #!/usr/bin/perl > > $a='$b is undefined'; > $a='$b is defined' if defined ($b); > print $a,"\n"; > print "b is now <$b>","\n"; > $a='$b is defined' if defined ($b); > print $a,"\n"; > __END__ > > produces > $b is undefined > b is now <> > $b is defined From the man page (actually my Texinfo conversion of the man page) under the section titled "Data Types and Objects", "...An undefined null string may become defined the first time you access it, but prior to that you can use the `defined()' operator to determine whether the value is defined or not." Therefore, accessing "$b" in the line `print "b is now <$b>", "\n";' makes $b defined instead of undefined. Cheers... -jeff Jeff Kellem Internet: composer@chem.bu.edu
rbj@uunet.UU.NET (Root Boy Jim) (03/23/91)
In article <1991Mar21.142935.11333@bmers145.bnr.ca> friedman@chekov.UU.NET (Barry Friedman) writes: > I've noticed the following non-intuitive behaviour of 'defined()': > When a variable is used in a string it becomes defined. This is a tricky situation. In LISP, mentioning an atom as a data object actually intern's it, but does not bind it. You cannot use the value cell until you set it to something. However, in perl, variables "spring to life" on reference, with "null or zero values as appropriate". In order to accommodate this, variables must become defined. I really don't like using defined for this reason, and shy away from it. -- [rbj@uunet 1] stty sane unknown mode: sane