in reply to Uninitialized value in string warnings (was: Warnings:)

Changing $a and $b to $u and $v. See perlvar for why.

$u ||= ''; $v ||= ''; my $c = $u . $v;
The quotes are unnecessary, concatenation is enough.

You can look up perl's trouble messages in perldiag, which you will have (in the most relevant edition) on your local perl box.

Update: A word of explanation and a caveat. The '||=' operator tests for truth and assigns if false. That makes mine fail if $u or $v is zero. vagnerr's ternary on defined() does not suffer from this flaw.

Update 2 AM: $a and $b are package global variables internally defined in perl. They act as temporaries within sort to hold the two values currently being compared. It is dangerous to tread on those. Good news for you, $foo ||= 'bar' is an expression which returns $foo's final value, so the code above could be written as:

my $c = ($u ||= '') . ($v ||= '');
or even:
my $c = (defined $u ? $u : '') . (defined $v ? $v : '');
The second does not modify $u and $v, and is well behaved for zero terms.

Concerning program design: it's a good idea to have a definite place where a variable is always given a defined value. That places the burden on one statement, and lets other sections of code forget about these problems. Just another form of loose coupling.

After Compline,
Zaxo

Replies are listed 'Best First'.
Re: Re: Warnings:
by Anonymous Monk on Jun 08, 2002 at 08:45 UTC

    I re-read the perlvar stuff, but I still don't understand the significance of the change from $a/b to $u/v?

    The code given is only an example, the real code uses descriptive variable names and has other constant info around the two vars.

    I had found perldiag, but was hoping for a quick way of finding a particular message, something like the perldoc -q re that works for perlfaq?

    The My $c = "$a$b" is a gross simplification of the real line. The problem is that the value of $b is set (or not) with the same compound statement. For me to ensure that it has a value requires me to break the compound statement into a loop in order to intercept and test the value of $b before using it, which I was hoping to avoid.

    However, I wasn't aware of the ||= operator, it will be useful in other situations. Thanks.

Re: Re: Warnings:
by Anonymous Monk on Jun 08, 2002 at 12:14 UTC

    Ok, understand about the potential clash of $a$b with the sort module, though it seems like bad design that I can clash with system vars that use common names. A problem with all languages that opt for implicitly global vars rather than implicitly local.

    I still don't see how your reference to perlvar would help me? The only occurences of $a or $b that I could find in there are where they are used in an example!

    I thought and tried inserting the bracketed ternary expressions into the compound expression as you suggested, but have so far been spectacularly unsucessful in preventing them from generating more and worse errors than I am trying to cure.

    I realise that this is probably down to my inexperience rather than because it isn't a good idea...so thanks!

    Re: Program design: Good, sage advice which in most any other situation I would totally agree with. Trouble in this case is that the variable ($b) in the original example, is actually generated within the compound statement and comes into existance and disappears automagically. I have successfully unwound the statement into a loop which allows me to preinitialise $b at an appropriate block level, but (so far) the syntatic salt needed to make it work within the compound statement eludes me. And as the unwound (looping) statement appears to be considerably less efficient that the compound one, disabling this individual warning for a block encompassing this one statement seems the appropriate way to go.