Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

I am totally new to Perl and trying to adapt some code...

the program starts like this:

1 #!/usr/bin/perl -w 2 # $Id: dtddiff,v 2.2 2005/07/16 03:22:57 ehood Exp $ 3 # Author(s): Earl Hood, <earl@earlhood.com> 4 # modified by Raul Suarez y Gonzalez 5 # POD at end of file. 67 use XML::Parser; 8 use File::Basename; 9 use Getopt::Long; 10 use SGML::DTDParse; 11 12 MAIN: { 13 my %opts = ( 14 'attributes' => 1, 15 'content-model-expanded' => 1, 16 'elements' => 1, 17 'general-ents' => 0, 18 'param-ents' => 0, 19 'verbose' => 0, 20 'ignore' => "", 21 'output' => "html", 22 ); 23 24 GetOptions(\%opts , 25 'attributes!', # Show attribute differences 26 'content-model-expanded!', # Show expanded content-models 27 'elements!', # Show element differences 28 'general-ents!', # Show general entity differences 29 'param-ents!', # Show parameter entity differences 30 'verbose!', 31 'ignore=s', # elements or entities to ignore in comparison 32 'output=s', # xml or html output 33 @SGML::DTDParse::CommonOptions 34 ) || SGML::DTDParse::usage(-verbose => 0, -exitval => 1); 35 SGML::DTDParse::process_common_options(\%opts ); 36 37 my $outfh = \*STDOUT ; 38 select ($outfh ); 39 $opts {'output'}=lc($opts {'output'});

A bit further in the program I reuse the variable opts in some subs:

980 sub output_print_h { 981 my $fh = shift ; 982 my $level = shift ; 983 my $text = shift ; 984 my $name = shift || undef ; 985 local (%opts ); 986 my $output = $opts {'output'}; 987 988 if($output eq 'html') { 989 print $fh "<a name=\"$name \">" if defined ($name ); 990 print $fh "<h$level >$text </h$level >"; 991 print $fh "</a>" if defined ($name ); 992 print $fh "\n"; 993 } 994 } 995 996 ##---------------------------------------------------------------- +----------## 997 998 sub output_print_footer { 999 my $fh = shift ; 1000 local (%opts ); 1001 my $output = $opts {'output'}; 1002 1003 if($output eq 'xml') { 1004 } 1005 else { 1006 print $fh "</body>\n</html>\n"; 1007 } 1008 } 1009 1010 ##--------------------------------------------------------------- +-----------## 1011 1012 sub output_print_header { 1013 my $fh = shift ; 1014 my $title1 = shift ; 1015 my $title2 = shift ; 1016 my $ens = shift ; 1017 my $ena = shift ; 1018 my $end = shift ; 1019 my $els = shift ; 1020 my $ela = shift ; 1021 my $eld = shift ; 1022 local (%opts ); 1023 my $output = $opts {'output'}; 1024 1025 if($output eq 'xml') {

The program appears to do what I want (by chance ?), but I get the following warning/error messages:

Use of uninitialized value $output in string eq at C:\PRIVATE\Tools\Pe +rl\site\bin/dtddiffrsg line 1025. Use of uninitialized value $output in string eq at C:\PRIVATE\Tools\Pe +rl\site\bin/dtddiffrsg line 1003.

Why do I get the warning/error for lines 1003 and 1025 while I do not get it for other lines, like e.g. 988?

Is it simply because at this stage of the development I only use html for $opts {'output'} ?

Many thanks

Replies are listed 'Best First'.
Re: Use of local :causes use of uninitialized variable warning/error
by jwkrahn (Abbot) on Nov 03, 2008 at 11:47 UTC

    I'm just wondering why you didn't get Can't localize lexical variable %s instead?   But it looks like that is because you have more than one %opts variable in your program.

    Anyway, local only works on package variables and hides the value(s) of that variable in the current scope.

    You should probably have a look at Coping with Scoping for more details.

    Update:   Also put these two lines at the beginning of your program:

    use warnings; use strict;

Re: Use of local :causes use of uninitialized variable warning/error
by JavaFan (Canon) on Nov 03, 2008 at 11:27 UTC
    Well, you ought to get a warning for line 988 as well. Each time, you localize %opts, then put $opts{output} into $output. However, if you localize %opts, you get a new (local) %opts. It's empty. Doesn't contain a single thing. So, it certainly won't contain a value of the key 'output'. Hence, $output will be undefined. Hence the warning.

    Why you don't get a warning for line 988 is a mystery to me. But it might be because you don't call the sub output_print_h.

Re: Use of local :causes use of uninitialized variable warning/error
by rasugo (Initiate) on Nov 03, 2008 at 11:20 UTC
    I posted the question while not realizing I was logged out. My apologies.