Placement of 'use', 'my'?

S

sgarfunkle

I've been placing 'use' statements as close as possible to the actual
invocation of the module's subroutines, sometimes even placing them in
a loop:

#Hypothetical code...
while (<>) {
if (/^new_student\t(.*)$/) {
use Student;
my $student = new Student($1);
}
}

The goal is to ensure that if I someday take that code out, the use
statement is taken out as well. Is this a safe, efficient thing to do?
As far as I can tell, the use statement is processed only once, at
compile time.

I haven't been following this placement philosophy with 'my' thus far;
I've been placing a single 'my' at the top of subroutines with all the
variables I want to use within it. As you can see from the above code,
though, I'd like to start placing the declaration closer to the
instantiation, even if it means going into the middle of a loop.
Again, is this a safe, efficient thing to do?

Why does Java force all class imports to be at the top of a file,
anyway? Are the reasons philosophical, or purely technical?
 
P

Paul Lalli

I've been placing 'use' statements as close as possible to the actual
invocation of the module's subroutines, sometimes even placing them in
a loop:

#Hypothetical code...
while (<>) {
if (/^new_student\t(.*)$/) {
use Student;
my $student = new Student($1);
}
}

The goal is to ensure that if I someday take that code out, the use
statement is taken out as well. Is this a safe, efficient thing to do?
As far as I can tell, the use statement is processed only once, at
compile time.
From the point of view of the program, it's perfectly safe. As you
say, the use will only be executed once, at compile time, even if it's
in a loop. However, from the point of view of a programmer, this leads
to what I would consider to be misleading code. A programmer or
maintainer who does not know that use happens at compile time might be
tempted to think the Student module is imported only if that regular
expression succeeds. This is wholly untrue, as the use is executed
before Perl even knows there's an 'if' statement there.

For this reason, I believe, the idiomatic practice is to place all `use
Module;` statements at the top of the script. [1]
I haven't been following this placement philosophy with 'my' thus far;
I've been placing a single 'my' at the top of subroutines with all the
variables I want to use within it. As you can see from the above code,
though, I'd like to start placing the declaration closer to the
instantiation, even if it means going into the middle of a loop.
Again, is this a safe, efficient thing to do?

This is not only safe and efficient, it is preferred. And not just in
Perl, in any language that allows variable declarations within
executable code. You should always declare your variables in the
smallest scope possible. This reduces the risk of variables
conflicting with same-named variables in other parts of the script, and
often prevents the need to re-assign an existing variable to the
"default" value (undef, '', 0, (), etc).

Lack of proper scoping is also often the cause of somewhat
difficult-to-diagnose bugs involving multidimensional structures.
Consider:

#!/usr/bin/perl
use strict;
use warnings;

my @arr = (1..10);
my @two_d;

for (1..10){
push @two_d, \@arr;
}
__END__

A naïve programmer might think this creates a 10x10 two-dimensional
array, in which every cell is independent from every other. However,
if you attempt to change any one cell in the grid, you will see nine
others change with it.

If @arr had been properly scoped to within the for loop, a reference to
a new array would have been added to the grid for each iteration, thus
correclty building the structure.
Why does Java force all class imports to be at the top of a file,
anyway? Are the reasons philosophical, or purely technical?

As to this, I have no idea. When I started programming, I was taught
C++ first, and only as an interesting side-note did the lecturer one
day go over C. One of the biggest things to get over was the inability
to declare variables whereever I wanted them.

Hope this helps,
Paul Lalli

[1] Lexically-controlled pragmas (such as integer, strict, and
warnings) are the exception to this rule. If you only want division
done not in floating point for a few statements, put `use integer`;
only in the block containing those statements.
 
T

Tassilo v. Parseval

Also sprach (e-mail address removed):
I've been placing 'use' statements as close as possible to the actual
invocation of the module's subroutines, sometimes even placing them in
a loop:

#Hypothetical code...
while (<>) {
if (/^new_student\t(.*)$/) {
use Student;
my $student = new Student($1);
}
}

The goal is to ensure that if I someday take that code out, the use
statement is taken out as well. Is this a safe, efficient thing to do?
As far as I can tell, the use statement is processed only once, at
compile time.

Yes, only once no matter how tight the loop it is it is placed in.
But then this is also a fairly idiosyncratic way of doing it. I anyway
wouldn't expect a compiletime directive in a while-loop, unless of
course it happens to be a lexically scoped pragma such as 'strict' or
'warnings'.
I haven't been following this placement philosophy with 'my' thus far;
I've been placing a single 'my' at the top of subroutines with all the
variables I want to use within it. As you can see from the above code,
though, I'd like to start placing the declaration closer to the
instantiation, even if it means going into the middle of a loop.
Again, is this a safe, efficient thing to do?

As a matter of fact this is the preferred way of doing it: Restrict each
of your variables to the tightest possible scope. If that means
declaring a lexical inside a loop, then do so. As for efficiency, there
is nothing to worry about either. A 'my' declaration happens at runtime
as well and internally the memory associated with the variable gets
reused where possible.
Why does Java force all class imports to be at the top of a file,
anyway? Are the reasons philosophical, or purely technical?

I am not familiar with the technical implications of Java's 'import'.
There might be technical reasons. Philosophical (as you put it) reasons
for sure. There is a certain logic behind putting things with a truely
global effect on top of a file. This is why you see this equally often
in Perl code.

Tassilo
 
J

Jay McGavren

Guess I'll reverse my habits, then: 'use's at the top of a file, 'my's
next to where the variable is used. Thanks for your input, everyone!
 

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

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,043
Latest member
CannalabsCBDReview

Latest Threads

Top