Re: does perl have a concept of "int main()"? (variable scoping question)
by LanX (Saint) on Dec 05, 2013 at 18:11 UTC
|
> In perl, it seems that all variables are visible to all functions by default, i.e. they have global scope.
nope Perl is not Python, it has lexically scoped variables.
Use my $var to declare pricate variables which are limited to the block-scope resp. the filescope at maximum.
Use our $var to declare variables in the local package which could be accessed from other namespaces by full declaration like $package::var.
Cheers Rolf
( addicted to the Perl Programming Language)
PS: see also this code example | [reply] [d/l] [select] |
Re: does perl have a concept of "int main()"? (variable scoping question)
by BrowserUk (Patriarch) on Dec 05, 2013 at 19:20 UTC
|
In perl, it seems that all variables are visible to all functions by default, i.e. they have global scope.
If you haven't discovered my, it's time to read up on it.
However, perhaps you've already discovered that and what you are getting at is that if you lay out your code like this (as many do):
my $mainVar1 = ...;
my $mainVar2 = ...;
while( something ) {
if( isSomething() ) {
my $result = doSomething();
doSomethingElse() if $result eq somthing;
}
}
exit;
sub isSomething {
...;
}
sub doSomething {
...;
}
sub doSomethingElse {
...;
}
Then all the variables -- including my vars -- declared for use by your main code, are visible to your subroutines. (And that can tempt people into 'cheating' by accessing them directly rather than passing them via arguments.
The (a, and my prferred) solution is to declare your subs at the top of the file and put your 'main' code at the bottom.
With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
| [reply] [d/l] |
Re: does perl have a concept of "int main()"? (variable scoping question)
by shmem (Chancellor) on Dec 05, 2013 at 20:34 UTC
|
Ah, perl variables. See perldata for starters.
Perl has global variables (and special global variables, see perlvar) which live in the symbol table of a package (or the "anypackage", i.e. they are available everywhere); then aliased specials, localized globals, lexically scoped, masked and state variables. Am I missing some?
The perl documentation provides a wealth of information about each variable kind. Start with perldata, look up my, our, local. The monastery has good writeups about various issues regarding each variable kind, i.e. my/local, space/time (was: Re: The difference between my and local).
By default, without useing strict, each variable is autovivified upon first use and its identifier stored in the symbol table of the current package, which defaults to main. The symbol table itself is a hash (default %main:: - note the two colons which are package identifiers/delimiters). The variables in each package are not globals - not even the variables in package main:
perl -le '$foo ="bar"; package Bar; print ">$foo<";package main; print
+ ">$foo<"'
><
>bar<
Well... that's for starters. I wish you a good time grinding manual pages and exploring the depths of this Monastery.
perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'
| [reply] [d/l] [select] |
Re: does perl have a concept of "int main()"? (variable scoping question)
by GrandFather (Saint) on Dec 05, 2013 at 20:09 UTC
|
I always use strictures (use strict; use warnings;), partly because I also have a strong C++ background, but mostly because strictures catch a lot of silly errors. To help with that I often start large scripts with:
use strict;
use warnings;
run()
sub run {
...
}
and put all the variables that would go in a C/C++ main into run. Note that the default package is ::main so it's best to avoid that for a sub name to avoid possible confusion. Note too that Perl doesn't need subs declared before they are used (unless you use prototypes, but don't do that) so the run sub can be given later in the file than where it is first used. That seems more natural to me - the overview at the top with more detail as you read through the script.
Oh, and really, don't use prototypes. With a C++ background you will want to, but they are not what you think and will cause grief.
True laziness is hard work
| [reply] [d/l] [select] |
|
|
| [reply] |
Re: does perl have a concept of "int main()"? (variable scoping question)
by Laurent_R (Canon) on Dec 05, 2013 at 19:03 UTC
|
Lexical variables declared (with my) outside of of any block or function will be visible until the end of the file. Lexical variables declared in a block or in a function will be accessible only until the end of the block or the function. You can create a pseudo main() function if you wish to reduce the scope of your variables.
| [reply] [d/l] |
|
|
{
my $var;
#... maincode ...
}
sub function1 {
# can't access $var
}
Cheers Rolf
( addicted to the Perl Programming Language)
| [reply] [d/l] |
|
|
Sure, blocks would be sufficient, I totally agree. But if you really want to mimic the C/C++ behavior (I am not really convinced by the idea, but let's assume you want to do it for the sake of argument), then you could have something like this:
use strict;
use warnings;
main();
sub main {
my $var1 = "foo";
my $var2 = "bar";
my $return_val = process_data ($var1, $var2);
# ...
}
then all your variables are truly "local" (I really mean lexically scoped). But I think that Perl offers better alternatives; trying to write C code in Perl is probably not a very good idea. I was only saying that it can be done if you really want to.
| [reply] [d/l] |
|
|