"my" declarations, only matter of taste?

Discussion in 'Perl Misc' started by Matija Papec, Sep 21, 2003.

  1. Matija Papec

    Matija Papec Guest

    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?


    --
    Matija
    Matija Papec, Sep 21, 2003
    #1
    1. Advertising

  2. On Sun, 21 Sep 2003 17:58:07 +0200, Matija Papec <> wrote:
    > 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?
    John J. Trammell, Sep 21, 2003
    #2
    1. Advertising

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

    Matija Papec <> wrote in
    news::

    >
    > 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-----
    Eric J. Roode, Sep 21, 2003
    #3
  4. 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

    --
    Chris Richmond | I don't speak for Intel & vise versa
    Chris Richmond - MD6-FDC ~, Sep 21, 2003
    #4
  5. 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
    --
    $_=q#",}])!JAPH!qq(tsuJ[{@"tnirp}3..0}_$;//::niam/s~=)]3[))_$-3(rellac(=_$({
    pam{rekcahbus})(rekcah{lrePbus})(lreP{rehtonabus})!JAPH!qq(rehtona{tsuJbus#;
    $_=reverse,s+(?<=sub).+q#q!'"qq.\t$&."'!#+sexisexiixesixeseg;y~\n~~dddd;eval
    Tassilo v. Parseval, Sep 21, 2003
    #5
  6. -----BEGIN PGP SIGNED MESSAGE-----
    Hash: SHA1

    On Sun, 21 Sep 2003 17:58:07 +0200, Matija Papec wrote:

    >
    > 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-----
    Brian Harnish, Sep 21, 2003
    #6
  7. Eric J. Roode <> wrote:
    > Matija Papec <> wrote in
    > news::
    >
    >>
    >> a)
    >> for (1..20) {
    >> my $mod = $_%3;
    >> ...
    >> }
    >>
    >> b)
    >> my $mod;
    >> for (1..20) {
    >> $mod = $_%3;
    >> ...
    >> }



    > 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?


    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
    Tad McClellan, Sep 21, 2003
    #7
  8. Chris Richmond - MD6-FDC ~ <> wrote:

    > 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.


    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
    Tad McClellan, Sep 21, 2003
    #8
  9. Chris Richmond - MD6-FDC ~ wrote:
    > 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
    Chris Mattern, Sep 21, 2003
    #9
  10. Abigail wrote:
    > Eric J. Roode () wrote on MMMDCLXXIII September
    > MCMXCIII in <URL:news:Xns93FD7E031ACEEsdn.comcast@206.127.4.25>:
    > // -----BEGIN PGP SIGNED MESSAGE-----
    > // Hash: SHA1
    > //
    > // Matija Papec <> wrote in
    > // news::
    > //
    > // >
    > // > 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.
    Peter Hickman, Sep 22, 2003
    #10
  11. Abigail wrote:
    > Peter Hickman () wrote on MMMDCLXXIV September
    > MCMXCIII in <URL:news:3f6ed7d7$0$24108$>:
    > !! 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.
    Peter Hickman, Sep 22, 2003
    #11
  12. In article <bkl1vu$pl3$-Aachen.DE>,
    "Tassilo v. Parseval" <> writes:
    >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

    --
    Chris Richmond | I don't speak for Intel & vise versa
    Chris Richmond - MD6-FDC ~, Sep 22, 2003
    #12
  13. In article <>,
    Steve May <> writes:
    >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

    --
    Chris Richmond | I don't speak for Intel & vise versa
    Chris Richmond - MD6-FDC ~, Sep 22, 2003
    #13
  14. In article <>,
    (Tad McClellan) writes:
    >Chris Richmond - MD6-FDC ~ <> wrote:
    >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

    --
    Chris Richmond | I don't speak for Intel & vise versa
    Chris Richmond - MD6-FDC ~, Sep 22, 2003
    #14
  15. In article <>,
    Chris Mattern <> writes:
    >Chris Richmond - MD6-FDC ~ wrote:
    >> 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.


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

    Thx, Chris

    --
    Chris Richmond | I don't speak for Intel & vise versa
    Chris Richmond - MD6-FDC ~, Sep 22, 2003
    #15
  16. -----BEGIN PGP SIGNED MESSAGE-----
    Hash: SHA1

    (Tad McClellan) wrote in
    news::

    > Eric J. Roode <> wrote:
    >> Matija Papec <> wrote in

    >
    >> 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?
    >


    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-----
    Eric J. Roode, Sep 22, 2003
    #16
  17. Matija Papec

    Eric Bohlman Guest

    (Chris Richmond - MD6-FDC ~) wrote in
    news:bkn5cp$qmi$:

    > 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.
    Eric Bohlman, Sep 22, 2003
    #17
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. kgs

    No matter solved it

    kgs, Dec 4, 2003, in forum: ASP .Net
    Replies:
    0
    Views:
    312
  2. psb
    Replies:
    1
    Views:
    388
    Ken Cox [Microsoft MVP]
    Jul 12, 2004
  3. vlsidesign
    Replies:
    6
    Views:
    421
    vlsidesign
    Jan 9, 2007
  4. Immortalist
    Replies:
    10
    Views:
    732
    Sir Frederick
    Nov 21, 2006
  5. David Pratt
    Replies:
    15
    Views:
    519
    Noah Roberts
    Dec 14, 2006
Loading...

Share This Page