"my" declarations, only matter of taste?

M

Matija Papec

a)
for (1..20) {
my $mod = $_%3;
...
}

b)
my $mod;
for (1..20) {
$mod = $_%3;
...
}

Let's say we'll need $mod only inside of foreach, so both cases work as
desired but is one more preferred then the other?
 
J

John J. Trammell

a)
for (1..20) {
my $mod = $_%3;
...
}

b)
my $mod;
for (1..20) {
$mod = $_%3;
...
}

Let's say we'll need $mod only inside of foreach, so both cases work
as desired but is one more preferred then the other?

I would prefer method (b). Why leave $mod hanging around
if you're done with it?
 
E

Eric J. Roode

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

a)
for (1..20) {
my $mod = $_%3;
...
}

b)
my $mod;
for (1..20) {
$mod = $_%3;
...
}

Let's say we'll need $mod only inside of foreach, so both cases work as
desired but is one more preferred then the other?

Case (a) limits the scope of $mod to the for loop block. In general, it
is good practice to limit the scope of variables as narrowly as possible,
since you're less likely to use its value by mistake later. Or, suppose
you later add a variable $mod in an enclosing outer scope. With case
(a), you don't have to worry about stomping on the new variable's value.
With case (b), you have two variables at the same scope that can
conflict.

Case (a) creates a new lexical variable each time through the loop; this
probably slows the loop down by some microseconds. That's almost
certainly inconsequential.

Case (b) is generally preferred, since it can potentially save you
headaches.

- --
Eric
$_ = reverse sort $ /. r , qw p ekca lre uJ reh
ts p , map $ _. $ " , qw e p h tona e and print

-----BEGIN PGP SIGNATURE-----
Version: PGPfreeware 7.0.3 for non-commercial use <http://www.pgp.com>

iQA/AwUBP23Qb2PeouIeTNHoEQL7WwCgrG8x+qqOrhO/Bt5shN3aUSOX86cAn2Yh
Ayxw3vcjJrOJocI0wZv2wewZ
=rCf0
-----END PGP SIGNATURE-----
 
C

Chris Richmond - MD6-FDC ~

If 'my' is so great, why does it disable the 'used only once'
warning from perl -w? I catch typos on a fairly regular basis
because I don't use 'my'. I also package all my subroutines and
libraries and call things explicitly. The environment I work
in has maybe 30 custom libraries. I'd be lost if I couldn;t
tell which file an error came from.

Chris
 
T

Tassilo v. Parseval

Also sprach Chris Richmond - MD6-FDC ~:
If 'my' is so great, why does it disable the 'used only once'
warning from perl -w? I catch typos on a fairly regular basis
because I don't use 'my'. I also package all my subroutines and
libraries and call things explicitly. The environment I work
in has maybe 30 custom libraries. I'd be lost if I couldn;t
tell which file an error came from.

Strictures will turn these warnings into a fatal error. Watch:

ethan@ethan:~$ perl -w
$variable = "foobar";
print $varaible;
__END__
Name "main::varaible" used only once: possible typo at - line 2.
Name "main::variable" used only once: possible typo at - line 1.
Use of uninitialized value in print at - line 2.

Whereas with strictures:

ethan@ethan:~$ perl -Mstrict
my $variable = "foobar";
print $varaible;
__END__
Global symbol "$varaible" requires explicit package name at - line
Execution of - aborted due to compilation errors.

So I don't need this warning any longer. It would serve no purpose and
given that the lower code wont even compile, emitting an additional
warning would be rather pointless.

Tassilo
 
B

Brian Harnish

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

a)
for (1..20) {
my $mod = $_%3;
...
}

b)
my $mod;
for (1..20) {
$mod = $_%3;
...
}

Let's say we'll need $mod only inside of foreach, so both cases work as
desired but is one more preferred then the other?

Use case a.

Variables should be limited to the the smallest possible scope.

- Brian
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.2 (GNU/Linux)

iD8DBQE/bhRViK/rA3tCpFYRAh3BAJ4w/S0nmJUCACZ9m4MYtkIUa28LgACg/kX4
1p8eOtpuITYTfWjux8bc4Cc=
=eB0T
-----END PGP SIGNATURE-----
 
T

Tad McClellan

Eric J. Roode said:
Case (b) is generally preferred, since it can potentially save you ^
^
headaches.


I'm pretty sure Eric meant to type an "a" instead of a "b" there.

Eric?
 
T

Tad McClellan

Chris Richmond - MD6-FDC ~ said:
If 'my' is so great,


It is not that lexical variables are so great.

It is that global variables (the alternative) are so bad.

I catch typos on a fairly regular basis
because I don't use 'my'.


You catch typos on a fairly regular basis because every variable
in your program is a global variable.

That will cause you great pain at some point in time.

You can have both (lexicals and typo detection) if you "use strict"
which you should be already doing anyway.
 
C

Chris Mattern

Chris said:
If 'my' is so great, why does it disable the 'used only once'
warning from perl -w? I catch typos on a fairly regular basis
because I don't use 'my'.

If you'd use "use strict", you'd catch even more. The idea
is to us "my" *and* "use strict". That way every variable
you didn't declare rings the bell.

Chris Mattern
 
P

Peter Hickman

Abigail said:
Eric J. Roode ([email protected]) wrote on MMMDCLXXIII September
MCMXCIII in <URL:// -----BEGIN PGP SIGNED MESSAGE-----
// Hash: SHA1
//
// //
// >
// > a)
// > for (1..20) {
// > my $mod = $_%3;
// > ...
// > }
// >
// > b)
// > my $mod;
// > for (1..20) {
// > $mod = $_%3;
// > ...
// > }
// >
// > Let's say we'll need $mod only inside of foreach, so both cases work as
// > desired but is one more preferred then the other?
//
// Case (a) limits the scope of $mod to the for loop block. In general, it
// is good practice to limit the scope of variables as narrowly as possible,
// since you're less likely to use its value by mistake later. Or, suppose
// you later add a variable $mod in an enclosing outer scope. With case
// (a), you don't have to worry about stomping on the new variable's value.
// With case (b), you have two variables at the same scope that can
// conflict.
//
// Case (a) creates a new lexical variable each time through the loop; this
// probably slows the loop down by some microseconds. That's almost
// certainly inconsequential.


Actually, for a small loop that you run many times, it may matter:

#!/usr/bin/perl

use strict;
use warnings;

use Benchmark qw /cmpthese/;

our $loop = 1000;

cmpthese -2 => {
inner => ' for (1 .. $::loop) {my $m = $_ % 3}',
outer => 'my $m; for (1 .. $::loop) { $m = $_ % 3}',
};

__END__
Benchmark: running inner, outer for at least 2 CPU seconds...
inner: 2 wallclock secs ( 2.04 usr + 0.00 sys = 2.04 CPU)
@ 1982.35/s (n=4044)
outer: 2 wallclock secs ( 2.11 usr + 0.00 sys = 2.11 CPU)
@ 2858.77/s (n=6032)
Rate inner outer
inner 1982/s -- -31%
outer 2859/s 44% --


Abigail

Just for completeness there is also

middle => ' for my $m (1 .. $::loop) { $m = $_ % 3}',

Which I favour which lies between the two.
 
P

Peter Hickman

Abigail said:
Peter Hickman ([email protected]) wrote on MMMDCLXXIV September
MCMXCIII in <URL:!! Abigail wrote:
!! >
!! > Actually, for a small loop that you run many times, it may matter:
!! >
!! > #!/usr/bin/perl
!! >
!! > use strict;
!! > use warnings;
!! >
!! > use Benchmark qw /cmpthese/;
!! >
!! > our $loop = 1000;
!! >
!! > cmpthese -2 => {
!! > inner => ' for (1 .. $::loop) {my $m = $_ % 3}',
!! > outer => 'my $m; for (1 .. $::loop) { $m = $_ % 3}',
!! > };
!! >
!! > __END__
!! > Benchmark: running inner, outer for at least 2 CPU seconds...
!! > inner: 2 wallclock secs ( 2.04 usr + 0.00 sys = 2.04 CPU)
!! > @ 1982.35/s (n=4044)
!! > outer: 2 wallclock secs ( 2.11 usr + 0.00 sys = 2.11 CPU)
!! > @ 2858.77/s (n=6032)
!! > Rate inner outer
!! > inner 1982/s -- -31%
!! > outer 2859/s 44% --
!! >
!! >
!! > Abigail
!!
!! Just for completeness there is also
!!
!! middle => ' for my $m (1 .. $::loop) { $m = $_ % 3}',
!!
!! Which I favour which lies between the two.


Well, that's something different. In both inner and outer, $_ iterates
from 1 to $::loop, and $m is derivated from that. If you make $m the
loop variable, and then do something like $m = $m % 3; in the loop,
you don't have the original value anymore.


Abigail

Oops. Should have read it slower.

"That just went on your permanent record" as they say.
 
C

Chris Richmond - MD6-FDC ~

Also sprach Chris Richmond - MD6-FDC ~:
Whereas with strictures:

ethan@ethan:~$ perl -Mstrict
my $variable = "foobar";
print $varaible;
__END__
Global symbol "$varaible" requires explicit package name at - line
Execution of - aborted due to compilation errors.>
So I don't need this warning any longer. It would serve no purpose and
given that the lower code wont even compile, emitting an additional
warning would be rather pointless.

Point taken. My secondary complaint is that with strict you
have to put 'my' or some global scope on every variable you
use. Its more typing and just that much more line noise.

thx, Chris
 
C

Chris Richmond - MD6-FDC ~

Chris Richmond - MD6-FDC ~ wrote:
Ah... I would say you are setting yourself up for other
problems by refusing to use 'my'.

I'm not refusing, I just don't like it that well. We've
developed this environment over maybe 5 years, and its quite
robust. Whatever pitfalls with/without 'my' have been
dealt with. Actually, one of the several developers does
use strict and my in his stuff. It works. I find the occational
laziness related to 'my' variables.
You might think about building a little routine to take advantage of
the argument form of the function 'caller'. I trap errors and feed
them to a caller trace routine I wrote that tells me exactly what
happened, where it happened and how it got there.

We've got something similar.

Thx, Chris
 
C

Chris Richmond - MD6-FDC ~

It is not that lexical variables are so great.
It is that global variables (the alternative) are so bad.

Right. For better or worse, all the subroutines are
packaged such that un-my'd variables act more like auto
variables in a C program. we treat them as local to
the routine.
You catch typos on a fairly regular basis because every variable
in your program is a global variable.

They "aren't." I realize that packages are just more globals
with an alternate name space.
That will cause you great pain at some point in time.

Its all been worked through.
You can have both (lexicals and typo detection) if you "use strict"
which you should be already doing anyway.

As I said in a previous followup, with the packaged subs, I can
treat unmarked variables local to the sub without having to
type 'my' in front of everything. Reduces typing and line noise.

my still disables 'used only once' detection, and strict doesn't
catch it either.

Thx, Chris
 
C

Chris Richmond - MD6-FDC ~

If you'd use "use strict", you'd catch even more. The idea
is to us "my" *and* "use strict". That way every variable
you didn't declare rings the bell.

I know. my and strict still don't catch unused variables
(used only once).

Thx, Chris
 
E

Eric J. Roode

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

(e-mail address removed) (Tad McClellan) wrote in
I'm pretty sure Eric meant to type an "a" instead of a "b" there.

Eric?

Yes, absolutely. My fingers choked up on the keyboard :)

Thanks for pointing out my mistake, Tad. I apologize, Matija.

- --
Eric
$_ = reverse sort $ /. r , qw p ekca lre uJ reh
ts p , map $ _. $ " , qw e p h tona e and print

-----BEGIN PGP SIGNATURE-----
Version: PGPfreeware 7.0.3 for non-commercial use <http://www.pgp.com>

iQA/AwUBP288vmPeouIeTNHoEQIkyQCgrkfLpDANmCVvxKfvapEfrIIlle0An2ym
sMxMxHkoML7aTPNzfFSiauff
=YHPl
-----END PGP SIGNATURE-----
 
E

Eric Bohlman

(e-mail address removed) (Chris Richmond - MD6-FDC ~) wrote in
Point taken. My secondary complaint is that with strict you
have to put 'my' or some global scope on every variable you
use. Its more typing and just that much more line noise.

For *tiny* programs (I'd define "tiny" here as "small enough that you can
comprehend the entire program in one glance") that might be true. But as
soon as you're writing anything bigger, having to think about the scope of
your variables is a Good Thing because it saves you from many hard-to-debug
problems. I've seen, for example, code where a variable gets changed each
time around a loop, and then code below the loop uses the value of the
variable in a situation where it's clear that the very last setting of the
variable wasn't what was wanted. Proper scoping protects you from that
kind of error.

And code in which all variables are essentially global in scope is
particularly difficult to maintain, because when you change one section of
the code you can't be sure how it will affect the rest of the code.
"Action at a distance" is something to be avoided. The hassle involved in
properly scoping your variables up front is considerably less than the
hassle of later trying to read through unrelated sections of your code in
order to figure out whether you can change a variable without stepping on
something else.
 

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,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top