Re: Use of uninitialized value in open second time but not first.
by varian (Chaplain) on Mar 30, 2007 at 19:32 UTC
|
The problem is related to the use of memory files. Apparently Perl issues the uninitialized warning upon the second time (and third etc) a memory file is created.
#!/usr/bin/perl -w
my $output;
print "first\n";
open (FH, '>', \$output);
print FH "Hello world\n";
close(FH);
$output=undef;
print "second\n";
open (FH, '>', \$output);
print FH "Hello world\n";
close(FH);
Output:
first
second
Use of uninitialized value in open at o4.pl line 10.
Seems to me like an overzealous action by Perl's warning system but nothing alarming so far.
Like said by the other monks you can set $output to the empty string as a workaround to avoid the warning alltogether. | [reply] [d/l] [select] |
Re: Use of uninitialized value in open second time but not first.
by sgifford (Prior) on Mar 30, 2007 at 18:41 UTC
|
This looks to me like perl weirdness. Setting $output to an empty string when it's declared seems to eliminate the warning.
| [reply] [d/l] |
Re: Use of uninitialized value in open second time but not first.
by Jenda (Abbot) on Mar 31, 2007 at 00:14 UTC
|
open my $FH, '>', \$output;
my $old_FH = select($FH);
print "Hello world\n";
select($old_FH);
Unless the code whose output you need to capture specificaly prints to STDOUT, this should work as well.
| [reply] [d/l] |
|
|
Thanks for the suggestion!
I actually don't know whether the code whose output I want to capture specifically prints to STDOUT (I didn't write it). I thought of the select solution too, but then I thought, "but what if it writes directly to STDOUT?" So I did this.
The solution I had actually works but produces the warning. I mention the "real" problem just in case I'm doing something brainless.
| [reply] [d/l] [select] |
Re: Use of uninitialized value in open second time but not first.
by mreece (Friar) on Mar 30, 2007 at 18:43 UTC
|
i don't know why it only warns the second time, or why it warns at all, but
my $output = '';
silences it..
| [reply] [d/l] |
Re: Use of uninitialized value in open second time but not first.
by Bro. Doug (Monk) on Mar 31, 2007 at 17:48 UTC
|
Excellent suggestions, monks.
I don't really see the problem in the same way, however. If the problem is here:
my $output; # this value is unintialized
open my $old_stdout, '>&=', \*STDOUT;
close STDOUT;
# Use of uninitialized value in open at the following line
open STDOUT, '>', \$output;
It's not an issue of 'spitting warnings at the second opening of a memory file'. $output really is uninitialized, and STDOUT, when its called, is already initialized. So it actually spits a warning the first time.
What I'm trying to say is that the warning is thrown more or less as expected. It's been pointed out that setting $output='' will fix the problem. Also... turning off 'use warnings' would probably silence it, but I wouldn't know because I never turn off warnings.
I hope this helps.
| [reply] [d/l] |
|
|
So it actually spits a warning the first time.
Where does that warning go? It's not on my screen when I run it. As I see it, $output is uninitialized both times, but the warning is not printed the first time.
I'm confused also because what I pass to open is a reference to $output which is always a real value regardless of whether $output is initialized or not.
| [reply] [d/l] [select] |
|
|
I see where I went wrong.
To give a more concise answer to this question, I got the code to run and saw the results just as you reported. So I started experimenting.
I noticed there are a lot of operations on references happening here, which makes me leery when you're mucking with global symbols (STDOUT, for instance). So I took $output and gave it persistence in scope:
our $output ; # changed 'my' to 'our'
The problem went away.
By the way, I agree with the monks who suggested using select().
Peace, monks.
| [reply] [d/l] |
Re: Use of uninitialized value in open second time but not first.
by GrandFather (Saint) on Jun 05, 2007 at 01:11 UTC
|
use strict;
use warnings;
wibble ();
wibble ();
sub wibble {
my $unicode16Str;
open my $UTF, '>:encoding(UTF-16LE)', \$unicode16Str;
print $UTF "Wibble";
close $UTF;
}
Generates:
Use of uninitialized value in open at noname1.pl line 10.
for the second call. However changing my $unicode16Str; to my $unicode16Str = '';
runs clean. Making $unicode16Str global to the sub is also fine. A closure issue perhaps?
DWIM is Perl's answer to Gödel
| [reply] [d/l] [select] |
|
|
| [reply] [d/l] |
|
|
| [reply] |
Re: Use of uninitialized value in open second time but not first.
by pmorch (Initiate) on Jul 19, 2007 at 11:22 UTC
|
Here is a shorter reproducing script. I wrote it before I decided to google for this problem... :D
#!/usr/bin/perl -w
use strict;
foreach (0..1) {
my $scalar;
open my $h, ">", \$scalar;
print "End of $_\n";
}
Similar to the OP, this generates a warning the second but not the first time through the loop.
But unlike the OP, it just fiddles with a my $h handle, not STDOUT or anything like that.
Similar to the OP, initializing with my $scalar = '' removes the warning, but isn't this a perl bug? Shouldn't $scalar be in the same state both times through the loop when it isn't initialized?
| [reply] [d/l] [select] |