RE: Trouble with variable scoping
From: Charles K. Clarkson [EMAIL PROTECTED] To: beginners@perl.org Date: Thu, 31 Aug 2006 10:41:33 -0500 Subject: RE: Trouble with variable scoping Roman Daszczyszak wrote: : In my perl script, I have a global variable called : @excludedIPAddresses, declared at the top of the script using : my. That sounds like a bad idea, but go on. It is but it's just for my convenience. The variables in question are ones that I change on the fly but do not want to type in repeatedly at the command-line or use a separate configuration file. They're at the top so I don't have to hunt for them. I did figure out I should just leave it 'my' scoped and pass the variable to the subroutine. Easier than trying to figure out how to make a global work.. at least for me. : When I run this, I get an error Can't localize lexical : variable. I understand that it's because the variable is : declared using my; what I don't understand is why, or what I : should declare the variable as, since if I leave out my I get : an error using use strict. Don't use local() in this circumstance. sub ExcludeIPAddress { my $ipAddress = shift; my $subnet = shift; return scalar grep /$ipAddress/, @excludedIPAddresses, $subnet-broadcast(), $subnet-base(); } HTH, It does, and I had thought about doing it that way, but I am still curious about the answer to my question, which I suppose is better stated: What is the scope of a variable that is declared at the top of a file using 'my'? I had thought that this would just make a variable that is scoped to the entire file, yet 'local' does not localize the variable in a subroutine, even though it (local) according to what I've read will 'save a global variable's value and reset it back upon the variable going out of scope'. That sounded exactly like the behavior I was after, yet it did not work. According to the error, 'local' does not work on lexically scoped variables.. so what other kinds of scoping are there? I only know of using 'my' to declare variables (which are scoped to the current block (which I understand) and are lexically scoped (which I don't)) because it's required by 'use strict'. I hope this helps explain my current confusion. Regards, Roman -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] http://learn.perl.org/ http://learn.perl.org/first-response
Re: Trouble with variable scoping
Roman Daszczyszak wrote: What is the scope of a variable that is declared at the top of a file using 'my'? I had thought that this would just make a variable that is scoped to the entire file, yet 'local' does not localize the variable in a subroutine, even though it (local) according to what I've read will 'save a global variable's value and reset it back upon the variable going out of scope'. That sounded exactly like the behavior I was after, yet it did not work. According to the error, 'local' does not work on lexically scoped variables.. so what other kinds of scoping are there? I only know of using 'my' to declare variables (which are scoped to the current block (which I understand) and are lexically scoped (which I don't)) because it's required by 'use strict'. Perhaps this will help explain better: http://perl.plover.com/FAQs/Namespaces.html John -- use Perl; program fulfillment -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] http://learn.perl.org/ http://learn.perl.org/first-response
Re: Trouble with variable scoping
Moon, John schreef: Maybe you want.. Use vars qw(@excludedIPAddresses); s/Use/use/, but: use vars has been antiquated by our(). -- Affijn, Ruud Gewoon is een tijger. -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] http://learn.perl.org/ http://learn.perl.org/first-response
Trouble with variable scoping
In my perl script, I have a global variable called @excludedIPAddresses, declared at the top of the script using my: use strict; use warnings; use Net::Ping; use Net::Netmask; use Net::NBName; use DBM::Deep; # User-configured variable declarations my @subnets = qw# 192.168.0.0/24 192.168.3.0/24 #;# @subnets should only contain CIDR-type subnet address blocks my @excludedIPAddresses = qw# 192.168.0.142 192.168.3.118 #;# @excludedIPAddresses can only handle specific IP addresses for now Further down, I use it in a subroutine: sub ExcludeIPAddress { # Argument(s): IP Address (string) and $subnet (object reference) # Returned: Boolean value corresponding to whether the IP should be excluded # Globals: Uses @excludedIPAddresses (in user-config section) my $ipAddress = shift @_; my $subnet = shift @_; # The next line does not work; I don't know why. local @excludedIPAddresses = @excludedIPAddresses; my $skip = 0; push(@excludedIPAddresses, ($subnet-broadcast(),$subnet-base())); $skip = grep /$ipAddress/, @excludedIPAddresses; # Commented out original working code # foreach my $exclude (@excludedIPAddresses) #{ #$skip = 1 if ($ipAddress eq $exclude); #} return($skip); } When I run this, I get an error Can't localize lexical variable. I understand that it's because the variable is declared using my; what I don't understand is why, or what I should declare the variable as, since if I leave out my I get an error using use strict. -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] http://learn.perl.org/ http://learn.perl.org/first-response
RE: Trouble with variable scoping
When I run this, I get an error Can't localize lexical variable. I understand that it's because the variable is declared using my; what I don't understand is why, or what I should declare the variable as, since if I leave out my I get an error using use strict. Maybe you want.. Use vars qw(@excludedIPAddresses); Hope this helps... jwm -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] http://learn.perl.org/ http://learn.perl.org/first-response
RE: Trouble with variable scoping
Roman Daszczyszak wrote: : In my perl script, I have a global variable called : @excludedIPAddresses, declared at the top of the script using : my. That sounds like a bad idea, but go on. : When I run this, I get an error Can't localize lexical : variable. I understand that it's because the variable is : declared using my; what I don't understand is why, or what I : should declare the variable as, since if I leave out my I get : an error using use strict. Don't use local() in this circumstance. sub ExcludeIPAddress { my $ipAddress = shift; my $subnet = shift; return scalar grep /$ipAddress/, @excludedIPAddresses, $subnet-broadcast(), $subnet-base(); } HTH, Charles K. Clarkson -- Mobile Homes Specialist Free Market Advocate Web Programmer 254 968-8328 Don't tread on my bandwidth. Trim your posts. -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] http://learn.perl.org/ http://learn.perl.org/first-response
Re: Trouble with variable scoping
On 08/31/2006 08:19 AM, Roman Daszczyszak wrote: In my perl script, I have a global variable called @excludedIPAddresses, [...] my @excludedIPAddresses = qw# 192.168.0.142 192.168.3.118 #;# [...] local @excludedIPAddresses = @excludedIPAddresses; [...] When I run this, I get an error Can't localize lexical variable. I understand that it's because the variable is declared using my; what I don't understand is why, or what I should declare the variable as, since if I leave out my I get an error using use strict. Declare it using 'our': our @excludedIPAddresses; -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] http://learn.perl.org/ http://learn.perl.org/first-response
Re: Trouble with variable scoping
Roman Daszczyszak wrote: In my perl script, I have a global variable called @excludedIPAddresses, declared at the top of the script using my: [...] When I run this, I get an error Can't localize lexical variable. I understand that it's because the variable is declared using my; what I don't understand is why, or what I should declare the variable as, since if I leave out my I get an error using use strict. The Cmy and Cour declarators have less to do with scope than with storage and access. Variables declared with Cmy are limited to the scope in which they are declared and any inner scopes, and are known as local or lexical variables. They may be re-declared within an inner scope, in which case the inner scope masks the outer, but the outer variable still exists, it retains its value, and it will be accessible again when control returns to the outer scope. For Cmy variables, storage is tied to the scope in which the variable is declared, in a scratchpad that is thrown away at the end of the scope. Cmy variables can also be global variables when declared in a large scope. Variables declared with Cour are tied to a package and are stored as part of the package, and are known as package variables. They are accessible anywhere in the package by using the short name or outside the package by using the fully qualified name (i.e. type-glyphpackage-name::variable-name). You can simulate the scoping rules of Cmy variables with the Clocal function(?). Clocal creates a copy of the _value_ of the outer package variable that masks any previous value. The new _value_ exists only within the scope in which the Clocal function was used. Clocal does not declare a variable unless you run without the 'strict' pragma. Without 'strict' it creates the package variable for you, but when using 'strict', it generates an error requiring you to either declare it with Cour or to fully qualify it with the package name. Mixing variables of the same name with different storage is where things are sometimes less clear. (And some of the rules have changed slightly through different revisions of perl.) So, generally you should avoid using variables of the same name with different storage declarators. When Perl sees code like: use strict; my $foo; local $foo; It first creates the lexical variable $foo. It then evaluates the call to Clocal by first trying to resolve the name of the variable it refers to. Since the only $foo it knows about is a lexical variable, it warns you that you are trying to use Clocal on a lexical variable. If you declare a package variable: use strict; my $foo; our $foo; local $foo; Perl will resolve the name $foo referenced in the call to Clocal to the package variable and will happily use it. IOW, the error comes about during the process of trying to resolve the variable name. If the variable name resolves to the wrong type of variable, you get an error. You could also help Perl to resolve the name by fully qualifying it: use strict; my $foo; local $PackageName::foo; __END__ Regards, Randy. -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] http://learn.perl.org/ http://learn.perl.org/first-response
Re: Trouble with variable scoping
Randy W. Sims wrote: Roman Daszczyszak wrote: In my perl script, I have a global variable called @excludedIPAddresses, declared at the top of the script using my: [...] When I run this, I get an error Can't localize lexical variable. I understand that it's because the variable is declared using my; what I don't understand is why, or what I should declare the variable as, since if I leave out my I get an error using use strict. The Cmy and Cour declarators have less to do with scope than with storage and access. Variables declared with Cmy are limited to the scope in which they are declared and any inner scopes, and are known as local or lexical variables. They may be re-declared within an inner scope, in which case the inner scope masks the outer, but the outer variable still exists, it retains its value, and it will be accessible again when control returns to the outer scope. For Cmy variables, storage is tied to the scope in which the variable is declared, in a scratchpad that is thrown away at the end of the scope. Cmy variables can also be global variables when declared in a large scope. Variables declared with Cour are tied to a package and are stored as part of the package, and are known as package variables. They are accessible anywhere in the package by using the short name or outside the package by using the fully qualified name (i.e. type-glyphpackage-name::variable-name). Variables declared with our() have the same scoping rules as variables declared with my(). $ perl -le' use warnings; use strict; package me; our $x = q/our/; my $y = q/my/; package main; print for $x, $y; ' our my John -- use Perl; program fulfillment -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] http://learn.perl.org/ http://learn.perl.org/first-response
Re: Trouble with variable scoping
John W. Krahn wrote: Randy W. Sims wrote: Roman Daszczyszak wrote: In my perl script, I have a global variable called @excludedIPAddresses, declared at the top of the script using my: [...] When I run this, I get an error Can't localize lexical variable. I understand that it's because the variable is declared using my; what I don't understand is why, or what I should declare the variable as, since if I leave out my I get an error using use strict. The Cmy and Cour declarators have less to do with scope than with storage and access. Variables declared with Cmy are limited to the scope in which they are declared and any inner scopes, and are known as local or lexical variables. They may be re-declared within an inner scope, in which case the inner scope masks the outer, but the outer variable still exists, it retains its value, and it will be accessible again when control returns to the outer scope. For Cmy variables, storage is tied to the scope in which the variable is declared, in a scratchpad that is thrown away at the end of the scope. Cmy variables can also be global variables when declared in a large scope. Variables declared with Cour are tied to a package and are stored as part of the package, and are known as package variables. They are accessible anywhere in the package by using the short name or outside the package by using the fully qualified name (i.e. type-glyphpackage-name::variable-name). Variables declared with our() have the same scoping rules as variables declared with my(). $ perl -le' use warnings; use strict; package me; our $x = q/our/; my $y = q/my/; package main; print for $x, $y; ' our my Sort of. This is one of Perl's weird features. I'm not quite sure how to define the behavior... The Cmy variable is scoped from the point of declaration to the end of the enclosing scope, which, in this case, is file scope. This is not unusual. The Cour declaration creates the package variable $me::x. If you add to the end of your example: use Data::Dumper; print Dumper \%me::; You'll notice that the symbol 'x' has been created as an alias for *me::x. So with Cour we are still talking about a package variable. What I'm unsure of is how the alias is set up. There is no symbol 'x' in main: print Dumper \%:: Both $x and $y are only valid from the point they are declared until the end of the file. If package 'me' were defined in a different file, both $x and $y would not be accessible from package 'main'. So I guess I don't really know technically how $x is resolved to $me::x from within main. Maybe it's quietly added to the lexical scratchpad for the file scope as an alias to the package symbol of the same name? If that is the case, then Cour and Cmy would always share the same scoping, but have different storage and access semantics. Randy. -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] http://learn.perl.org/ http://learn.perl.org/first-response