Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

perl implementation of defined/undefined for a variable

As a 75 year old C/C++ programmer, I am wedded to strongly typed languages. This makes it difficult for me to learn perl. In particular, the question of the defined/undefined attribute is very difficult for me to grok. Here's the deal:

My introductory perl book tells me that an undefined numeric variable returns 0 and an undefined array variable returns the empty string. Both values are valid for their respective types. (I am told that I am not supposed to express opinions here, but still I wonder what my program will do with these variable values if I mistakenly thought they were defined.) Anyhow, it is apparent that a perl variable must be implemented with a data structure that contains a defined/undefined indicator. Is this the case?

I have spent a good bit of time cruising the web for an answer, but nobody seems to recognize the issue.

I didn't read the perl source, and I don't know what else I could have tried.

like image 614
John Avatar asked Apr 19 '26 16:04

John


2 Answers

Yes, Perl variables are backed by internal data structures (called SVs) that include a flag to indicate whether a value is defined. So you're right — Perl keeps track of whether a variable is defined or not. When you use an undefined variable, Perl tries to handle it gracefully: in numeric context it becomes 0, and in string context it becomes an empty string "". But this can easily hide bugs if you're not careful. To catch such mistakes, always use use strict; use warnings; and check with defined($var) when needed.

like image 118
Sakura Yamamoto Avatar answered Apr 22 '26 01:04

Sakura Yamamoto


This contains a few comments that I think may be worth assembling into an answer, in particular as some of it has not been addressed in the existing answers


My introductory perl book tells me that [...] an undefined array variable returns the empty string

The statetement is incorrect, what is not addressed by the answers existing at this time.

An array that has only been declared is thought of as empty (or uninitialized of course, but not "undefined") and will return an empty list when evaluated, so literally nothing. An "empty string" is a value of a kind (that can be stored in a variable or added to a container) so an array with that would have that one element. The code

my @ary; 
say "|$_|" for @ary;   # prints nothing at all

prints nothing at all since it's asked to iterate over an empty list, what @ary evaluated to. (An array, like @ary here, is a persistent variable for which there is a data structure in memory, even when it is "empty" -- has no values associated with it.) No empty strings (||) are printed.

The following is mentioned in the answers but I'd like to point it out:

I wonder what my program will do with these variable values if I mistakenly thought they were defined

[refers to uninitialized scalar/array variables]

It emits warnings when you use them in a way that needs values. If they are merely tested for truth then that is considered legitimate and "false" -- my $x; if ($x) { ... } is ok (and that block/branch is not evaluated at all). (There may be other cases where it's ok to use them?) So you do get somethin'. If that doesn't do it for you, one can make warnings fatal.

As for the notion of defined/undefined,

... the question of the defined/undefined attribute is very difficult for me to grok

(I'd suggest to carefully read "Scalar values" in perldata.)

For me my $n; is quite a bit like int n; in C/etc. It's declared and uninitialized. So don't use it as such. Except that it'll allow that (with a warning emitted!) while it also adds conveniences -- it may be used as a flag and it is converted to reasonable values if used.


Let me comment on the notion of an "emtpy string," a null string of length zero.

Right after my $x; that $x scalar variable is "uninitialized," or perhaps we can say "undefined" in the sense that defined $x returns a "falsey" value -- a "boolean" (which isn't specified while it's usually an empty string) which makes an if test fail. It is a special type of a null string that has no value at all. (See Scalar values in perldata, for instance.) An undefined scalar may also be tested for truth directly, if ($x), and is false.

But after my $x = ''; that $x has a (string-type) value that can be legitimately used as a string, without warnings emitted. It may be concatenated with another string, printed, etc. It's a string of length zero.

the term "undefined" is really used for values while for a variable one says "uninitialized," while this distinction gets blurred very easily

like image 43
zdim Avatar answered Apr 22 '26 02:04

zdim



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!