BEGIN and lexicals

C

cate

I have a large list of my vars that I would like to get out of the
way; place them at the end of the script - kinda a class thing.

Is there a way to use BEGIN some how? Something like this. I
suspect you can't, but I'm asking the pros.

use strict;
code using $var1 ...
code using $var1 ...
more code


BEGIN {
my $var1 = 'sfsdf';
my $var2 = 'sdfsdf';
}

thank you
 
M

Marc Girod

Is there a way to use BEGIN some how?   Something like this.  I
suspect you can't

Their scope will be this of the BEGIN block.
You could do:

use vars qw($var1 $var2);

....

BEGIN {
$var1 = 'sdfsdf';
$var2 = 'sdfsd';
}

Now, should I say that I am not convinced it buys you much...

Marc
 
C

ccc31807

I have a large list of my vars that I would like to get out of the
way; place them at the end of the script - kinda a class thing.

Is there a way to use BEGIN some how?   Something like this.  I
suspect you can't, but I'm asking the pros.

Put them in a separate file, either an ordinary file or a PM.

If in an ordinary file, say vars.txt, like this:
$var1=GWashington
$var2=12
$var3=ashington, D.C.

You can do this in your script:
my %vars;
open VARS, '<', 'vars.txt';
while (<VARS>) {
chomp;
my ($key, $val) = split /=/;
$vars{$key} = $val;
}
close VARS;

If in a Perl module, say VARS.pm, use them like this in your script:

use VARS;
print $VARS::var1; # prints GWashington
$product = $VARS::var2 + 3; # $product is 15

In package VARS declare your variables with our.

CC.
 
U

Uri Guttman

MG> Their scope will be this of the BEGIN block.
MG> You could do:

MG> use vars qw($var1 $var2);

MG> ...

MG> BEGIN {
MG> $var1 = 'sdfsdf';
MG> $var2 = 'sdfsd';
MG> }

MG> Now, should I say that I am not convinced it buys you much...

it buys you the loss of lexicals. those are now package globals and can
be accessed from anywhere in the program.

uri
 
U

Uri Guttman

c> I have a large list of my vars that I would like to get out of the
c> way; place them at the end of the script - kinda a class thing.

c> Is there a way to use BEGIN some how? Something like this. I
c> suspect you can't, but I'm asking the pros.

c> use strict;
c> code using $var1 ...
c> code using $var1 ...
c> more code


c> BEGIN {
c> my $var1 = 'sfsdf';
c> my $var2 = 'sdfsdf';
c> }

the lexicals will be scoped only to the BEGIN block so they won't be
seen by the rest of the code. but needing to declare a mess of lexicals
tells me you have a weak design for this program. they are effectively
file globals and needing many globals is a poor design. try declaring
them in tighter scopes where they are just needed. use subs to organize
mainline code into smaller scopes where you can declare lexicals you
only need there. there should be almost no mainline code (code outside
subs) in any decent sized script. this will help with flow control,
understanding the code, maintaining it, etc. if you need a long flow,
still break it up into subs and call them from higher level subs. and do
that again if you have long higher level subs.

another solution is to use a single lexical hash with many/most of your
lexical data. it may need you to rewrite code that refers to them but
that be done quickly with a search/replace edit call. then you declare
the lexical hash at the top and initialize it in the BEGIN at the
bottom.

uri
 
J

Jürgen Exner

cate said:
I have a large list of my vars that I would like to get out of the
way; place them at the end of the script - kinda a class thing.

As a general rule you should try to avoid global variables, they are
rarely necessary. And a large number of global variables usually
indicates poor design of the algorithm or the data structure.

Instead of trying to hide the variables I would rather investigate how
to improve my code or data structure and eliminate them.

jue
 
B

Brad Baxter

I have a large list of my vars that I would like to get out of the
way; place them at the end of the script - kinda a class thing.

Is there a way to use BEGIN some how? Something like this. I
suspect you can't, but I'm asking the pros.

use strict;
code using $var1 ...
code using $var1 ...
more code


BEGIN {
my $var1 = 'sfsdf';
my $var2 = 'sdfsdf';
}

thank you

You have gotten advice against wanting to do this,
and I concur that your motives are perhaps dubious.

But to answer the specific question, you just need
to declare the lexicals at the top and assign them
in the BEGIN block at the bottom *without* my.

1 #!/usr/local/bin/perl
2
3 use warnings;
4 use strict;
5
6 my $var1;
7 my $var2;
8
9 print "$var1, $var2\n";
10
11 exit;
12
13 BEGIN {
14 $var1 = 'Hello';
15 $var2 = 'World';
16 }
17
18 __END__
19 Hello, World
 
U

Uri Guttman

BB> But to answer the specific question, you just need
BB> to declare the lexicals at the top and assign them
BB> in the BEGIN block at the bottom *without* my.

then you don't solve his problem of a large list of vars at the
beginning of the script!

uri
 
R

RedGrittyBrick

cate said:
I have a large list of my vars that I would like to get out of the
way; place them at the end of the script - kinda a class thing.

Is there a way to use BEGIN some how? Something like this. I
suspect you can't, but I'm asking the pros.

use strict;
code using $var1 ...
code using $var1 ...
more code


BEGIN {
my $var1 = 'sfsdf';
my $var2 = 'sdfsdf';
}

As Uri and Jürgen suggested, I'd try hard not to have a large list of
vars anywhere. I'd declare variables in the smallest useful scope, near
where they are used.

If forced to have a large list, since I prefer not the have BEGIN blocks
at the end - I'd try something like:

-----------------------------8<-------------------------------
#!perl
use strict;
use warnings;

{ # to restrict scope of %vars

my %vars = getVars();
# ...
print $vars{'var1'};
# ...
}

sub otherSub {
# no use of %vars possible here as it's lexical & hence out of scope?
}

sub getVars {
return (
var1 => 'sfsdf',
var2 => 'sdfsdf'
)
}
-----------------------------8<-------------------------------

Which I think avoids creating/using global variables
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,818
Latest member
Brigette36

Latest Threads

Top