Re: Unable to declare local variable with "use strict".
by ikegami (Patriarch) on Mar 26, 2010 at 20:33 UTC
|
local doesn't declare a variable. It just makes a temporarily backup of one.
You can use our to effectively disable strict 'vars' for a variable.
#!/usr/bin/perl -w
use strict;
our $type;
ref_test1();
sub ref_test1
{
local $type="connect";
print "Here in ref_test1.\n";
ref_test2();
}
sub ref_test2
{
print "Type: $type\n";
print "Here in ref_test2\n";
}
or
#!/usr/bin/perl -w
use strict;
ref_test1();
sub ref_test1
{
local our $type="connect";
print "Here in ref_test1.\n";
ref_test2();
}
sub ref_test2
{
our $type;
print "Type: $type\n";
print "Here in ref_test2\n";
}
However, the following is better because it's more loosely coupled:
#!/usr/bin/perl -w
use strict;
ref_test1();
sub ref_test1
{
print "Here in ref_test1.\n";
ref_test2("connect");
}
sub ref_test2
{
my ($type) = @_;
print "Type: $type\n";
print "Here in ref_test2\n";
}
| [reply] [d/l] [select] |
|
|
So, I can not use local with use strict? I would use our but I will be using it in threads and I don't feel safe to use because there is no scope for it.
Is it safe to use our with threads?
Thanks for Everyones response.
| [reply] |
|
|
So, I can not use local with use strict?
I just gave two examples that use local and strict.
I don't feel safe to use because there is no scope for it.
Local only works on package (global) variables. You can't use local on lexical (scoped) variables.
(Well, it also works hash elements and array elements, but I don't see how that could be useful here.)
Is it safe to use our with threads?
In Perl threads, each thread has its own variables unless you share them explicitly. This applies to both lexical (scoped) and package (global) variables.
| [reply] |
|
|
Strict makes you declare your variables. Local does not declare a variable... it makes a backup copy of an existing global variable, and that global is still global. my declares a local variable. my is what you want to use.
| [reply] [d/l] [select] |
|
|
|
|
|
|
I think you should first make up your mind what kind of variables you would like to have. We should not use the term "local variable" in Perl, since it is not clear what this means. Perl has two type of variables: Lexical variables, and package global variables. Which one would you like to use?
Lexical variables are declared using my or state - the latter only if you are using Perl 5.10, and if feature 'state' is enabled.
Package global variables do not need to be declared. They can be declared using our. If you decide not to declare them, and have strict in effect (which is for sure a good idea), you have to qualify them with the full package name.
local is a function which operates on package global variables. Hence if you use it, and have strict in effect, you need to qualify the variable name with the package.
My impression is that a lot of the confusion about your posting arose, because you did not explain in the first place what kind of variable you want to use, so some people thought you are interested in lexicals (and suggested to use my), while others thought you want to have package globals (and suggested to use our).
--
Ronald Fischer <ynnor@mm.st>
| [reply] [d/l] [select] |
|
|
|
|
|
|
|
|
|
| [reply] [d/l] |
|
|
|
|
|
Re: Unable to declare local variable with "use strict".
by kennethk (Abbot) on Mar 26, 2010 at 20:30 UTC
|
You may find a read through of local informative, particularly the first line:
You really probably want to be using my instead, because local isn't what most people think of as "local".
This might also be confusion on your part about what strict does. As best as I can tell, your code (maybe) does what you expect by declaring a $type variable at the script level and swapping your local statement to a my - this results in creating a localized $type variable in ref_test1 and a closure around the script-level variable in ref_test2:
#!/usr/bin/perl -w
use strict;
my $type = "some line";
ref_test1();
sub ref_test1
{
my $type="connect";
print "Here in ref_test1.\n";
ref_test2();
}
sub ref_test2
{
print "Type: $type\n";
print "Here in ref_test2\n";
}
__END__
Here in ref_test1.
Type: some line
Here in ref_test2
| [reply] [d/l] [select] |
Re: Unable to declare local variable with "use strict".
by doug (Pilgrim) on Mar 27, 2010 at 14:57 UTC
|
It looks like fuzzy thinking to me. You have two subroutines and you want then to share a variable, but you don't want that variable visible anywhere else. The answer to this is closures.
Since subroutines form a closure, the easiest way is to declare ref_test2() inside the body of ref_test1(). ref_test2() will have access to everything ref_test1() does, Note that creating a named subroutine puts a global entry in the symbol table, ref_test2() could still be called from outside of ref_test1() and still see the exact same variables.
But I don't like nested subroutines under any circumstances, so I wouldn't go there. I'd do it like this:
{ # start closure
my $type;
sub ref_test1() {
...
}
sub ref_test2() {
...
}
} # end of closure
which allows both to read/write/whatever $type as much
as they like, yet $type is still invisible to the outside world.
- doug
PS: Someone posted that since ref_test1() was calling ref_test2() directly, then you should pass $type as a parameter, and I agree completely. I'm guessing that this example is simplified, and that in the real example ref_test2() can be called from other places too. | [reply] [d/l] |
Re: Unable to declare local variable with "use strict".
by planetscape (Chancellor) on Mar 26, 2010 at 20:30 UTC
|
| [reply] |
|
|
Changing the local into a my will give the same error.
| [reply] |