Re: [vox-tech] perl redux - references
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [vox-tech] perl redux - references
- Subject: Re: [vox-tech] perl redux - references
- From: Micah Cowan <micah@coMAPSwanbox.com>
- Date: Mon, 09 Apr 2001 11:33:40 -0700
- References: 20010408094047.A14621@dirac.org
On Sun, Apr 08, 2001 at 09:40:48AM -0700, Peter Jay Salzman wrote:
> this stuff is way above my head.
>
> here is a program (that works) which reads a text file with lines of the form
>
> James = "William"
> Leonard = "DeForest"
> Montgomery = "James"
>
> and sets the variable $James to "William", and so on. note that line 3 is
> commented out.
>
> 1 #!/usr/bin/perl -w
> 2 use diagnostics;
> 3 #my $James;
> 4
> 5 open("FP", "< config");
> 6 while(<FP>) {
> 7 chomp;
> 8 /^(\w+)\s+=\s+\"(.*)\"/;
> 9 $$1 = $2;
> 10 }
> 11 close(FP);
> 12 print ": $James\n";
>
> the only error message is that this code produces is that "$James" might to a
> typo because it appears only once in the code. fair enough. so i uncomment
> line 3. NOW the error message is that $James is uninitialized.
>
> i don't completely grok scoping in perl, but this seems ridiculous. why would
> perl complain that the variable is uninitialized?
>
> pete
You asked for warnings, you got 'em :)
Warnings tend to be helpful only when you're trying to write "kosher"
code (a la "use strict"). If you're /trying/ to be kludgey, they'll
just get in the way ;).
The code you've written works, as you've pointed out, but your code
essentially "tricks" Perl into instantiating $James, so you're kinda
on your own.
Believe it or not, IIRC, the $James defined on line 3 and the $James
you refer to via $$1 are completely different $James'es. I'd guess
you didn't notice that the output is empty when you uncomment line 3?
The $$1 creates a *global* $James, aka $main::James or $::James,
whereas the "my" creates a lexically-scoped local. So in all of your
"normal" uses of $James (in the print statement), you are referring to
the lexically-scoped $James, whose name obscures the visibility of the
global one, unless you specifically refer to $::James. However, when
you /set/ James via $$1, it goes directly to the global name table.
To get rid of warnings, use "our" instead of "my" (won't work on some
older Perls - like, say, the one I'm using to test it right now from
work :( ), or "use vars qw($James);", etc. Then the declaration
will correctly refer to the global $James.
HTH,
Micah
|