Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

local vs my

by rzward (Monk)
on Sep 02, 2002 at 14:27 UTC ( #194587=perlquestion: print w/ replies, xml ) Need Help??
rzward has asked for the wisdom of the Perl Monks concerning the following question:

Hello,

I have a script that makes heavy use of 'local' rather than 'my'. This is because the script was originally written in 1996 and supporting Perl 4 was important. I have updated and enhanced the script quite a bit and have up to now decided to not use 'my' because I didn't see a real need.

I would now like to use 'use strict' but 'use strict' doesn't regard 'local' as a way of defining a variable, so I get many "... requires explicit package name at..." messages.

I remember reading somewhere that 'local' works whereas 'my' doesn't when dealing with file handles... Am I remembering incorrectly? I can't find this.

I am now considering changing all occurrences of 'local' in the script to 'my' but am worried that this will break the code. Are there places where I can read about the differences between 'my' and 'local'?

Thanks in advance.

Richard

Comment on local vs my
Re: local vs my
by kvale (Monsignor) on Sep 02, 2002 at 14:37 UTC
    Online you could look at the perlsub manpage for a detailed explanation of the differences between local and my. In print, look at the book "Programming Perl". I have converted scripts from local to my, and except for filehandles and typeglobs, most convert without too much problem.

    -Mark

Re: local vs my
by Vennis (Pilgrim) on Sep 02, 2002 at 14:40 UTC
    Hi,
    there are also references in the Local function description (including the reference to perlsub).
Re: local vs my
by davorg (Chancellor) on Sep 02, 2002 at 14:43 UTC
    I would now like to use 'use strict' but 'use strict' doesn't regard 'local' as a way of defining a variable, so I get many "... requires explicit package name at..." messages.

    That's because local doesn't define variables. It merely changes the value in an already existing package variable.

    I remember reading somewhere that 'local' works whereas 'my' doesn't when dealing with file handles... Am I remembering incorrectly? I can't find this.

    That's right. Filehandles only ever exist as package "variables" in typeglobs. You have to localise them with local you can't create lexical filehandles with my - although you can now create lexical filehandle objects with syntax like:

    my $fh = IO::Handle->new;
    I am now considering changing all occurrences of 'local' in the script to 'my' but am worried that this will break the code.

    There's a chance that this will break your code. The best way to make your script "strict-clean" is to define all of your variables at the file level with use vars or our.

    Are there places where I can read about the differences between 'my' and 'local'?

    I like Dominus' articles Coping With Scoping and Seven useful uses of local.

    --
    <http://www.dave.org.uk>

    "The first rule of Perl club is you do not talk about Perl club."
    -- Chip Salzenberg

      That's right. Filehandles only ever exist as package "variables" in typeglobs. You have to localise them with local you can't create lexical filehandles with my

      What about this?

      open(my $fh, 'somefile') || die $!;

        What about this?

        open(my $fh, 'somefile') || die $!;

        When calling open with an undefined variable for the indirect filehandle ($fh in this case), open will stick a reference to the "real" filehandle in the indirect filehandle. $fh is a lexical, what it refers to is not.

        — Arien

        Excellent point. But that is, of course, a relatively new innovation :)

        --
        <http://www.dave.org.uk>

        "The first rule of Perl club is you do not talk about Perl club."
        -- Chip Salzenberg

Re: local vs my
by Ay_Bee (Monk) on Sep 02, 2002 at 14:47 UTC
    in addition to checking out the manual refs for my and local a look at "our" could be of help.
    The easy first step to look for documentation is :- perldoc -f command eg perldoc -f our
    Ay_Bee
    -_-_-_-_-_-_-_-_-_-_-_- My memory concerns me - but I forget why !!!

      Maybe have a look at Why is 'our' good? by our tilly first...

      --
      Until you've lost your reputation, you never realize what a burden it was or what freedom really is. -Margaret Mitchell

Re: local vs my
by Courage (Parson) on Sep 02, 2002 at 14:49 UTC
    In a C world I succesfully used #define small xsmall in similar situations.

    I guess, using preprocessor will not work in your case? You could start here to check whether things immediately break or may be will be working some time...

    Courage, the Cowardly Dog

Re: local vs my
by JupiterCrash (Monk) on Sep 02, 2002 at 14:56 UTC
    A difference between the 'my' function and the 'local' function that is not immediately obvious after reading their descriptions is illustrated by running the below snippet. It shows that 'my' is a bit more powerful, it keeps the variable's value completely within the block. While local allows calling subs to also access the variable's value within that block. Unless there are areas in your program that _expect_ this behavior, you should be fine changing everything to 'my'.
    sub a { print "localVar is : $localVar \n"; print "myVar : $myVar \n" } sub b { local ($localVar); my ($myVar); $localVar = "I am localVar."; $myVar = "I am myVar."; &a; } # main &b;
Re: local vs my
by rzward (Monk) on Sep 02, 2002 at 15:24 UTC
    Thank you all for your replies.

    I am now reading the above-referenced articles and am looking into changing 'local' to 'my' in certain instances and in other instances where 'local' is necessary, using 'use vars' and 'our' as ways of making 'use strict' happy.

    Richard

      Hi rzward!

      Just a short thought on using 'our' and 'use vars' everywhere... You could also do what use strict wants you to do: Fully qualify all the variables you use.

      There's quite a difference between a true global variable (as defined with use vars or our or my at file scope), and something like $Package::variable (which is also global in the sense that it's accessible from outside of the package that defined it).

      First and foremost, you'll keep fully qualified variables out of the namespace (read "way") of other modules/packages/namespaces.

      BTW, has someone mentioned file scoped lexicals? That's my-definitions at the file level, outside of all subroutines, or BEGIN/END blocks. These are global to anything within the physical file they're defined in. Are they in any way more/less effective than globals? Gut knowledge anyone? If your scipt is monolithic (in one file) you could use those, too.

      Most of your local variables will acually be lexically scoped variables (my-variables). If there are some spots in your code where the behavior of local is really needed, it's still fine to use a fully qualified variable.

      Since your script was meant to support perl4, too, it's acutally quite likely that merely substituting local with my will break your code -- however, I'd still give it a quick shot to get some orientation how much of a problem you really have. I could also imagine writing a short script that analyzes the your code to help you determine where work is needed (isn't there some perl4_to_perl5 converter out there?).

      For example, if there are any local variables that are solely used within one block, and never mentioned outside that block, you can safely make them my vars. If however, a variable is used in the caller of a function, AFTER the function returned (mind loops!) you probably can't just go ahead and define it as a my variable.

      Also, you should check whether using local everywhere (in subroutines) was just a habit of the author of your script, or if it's been used in a determined way. If it was a habit, substituting with my will be less of a problem I'd assume.

      It all depends on the size of your project, but in any way, you seem to have some work to do... ;)

      So long,
      Flexx

        There's quite a difference between a true global variable (as defined with use vars or our or my at file scope), and something like $Package::variable (which is also global in the sense that it's accessible from outside of the package that defined it).
        That's not true. Do not confuse file scoped lexicals variables such as my and our can declare with package scoped globals ones which is what the vars pragma declares, which are exactly $Package::variables.

        Makeshifts last the longest.

Re: local vs my
by clintp (Curate) on Sep 03, 2002 at 00:31 UTC
    Here's a question: why the obsession with 'use strict' in a script that already works and you're just maintaining?

    If 'use strict' doesn't do what you want, chuck it. Get what you need from warnings, strict 'subs' and strict 'refs'. Ignore the peer pressure telling you that everything has to 'use strict'. It doesn't.

      Well, the answer from "received wisdom" is that maintenance often involves adding or modifying functionality, which may entail using new variables, and if there's no clear pattern for making up variable names, and you're not paying attention, ... etc.

      But your point is well taken, and it's worth noting that even without "use strict", you can still declare variables with "my" to get the intended effect of scoping, just to make sure a newly added variable doesn't trounce a "legacy" variable that happens to have the same name.

      Hmmm.. IMHO, it depends on the forseeable future such a script will be exposed to. If you know you will change/add to the script again, I'd rather start using strict sooner than later... If that, however, keeps me from accomplishing my work at the time I planned, I'd chuck it, without second thought, too.

      Regardless of that, if I'd inherit maintenance of someone else's obsolete script, the first thing I'd do anyway is to work through the code (most likely making lots of changes). And I'd be sure to cure it from overuse of local, no matter whether I use strict or not.

      It's not about blindly obeying the strict dogma -- it's about bringing the script up to date.

      So long,
      Flexx

      In many instances I would view this question as a good one simply because I think that traditions, which many who ask this same question might also view the use of 'use strict' as a pragmatic tradition for which there is no real good reason to use it other than 'everybody else does it', should be questioned now and then. However, it has been stated many times past and now present (again) the purpose of use strict in all its glory (tm).

      Clean coding practice not only helps you but it helps those who maintain your code after you. If 'use strict' complains about something, fix it! Don't just stop using strict :). There is a reason such tools are available to us to use. Alas, to each his own. I methodically make use of the use strict pragma and I am grateful that it is there for me to use.

      If there is something specifically in your code that you don't want to use strict for then turn strict off for that bit of code and then turn it back on afterward :). I'd make sure I would comment why I am turning it off, though. That could be very useful to the maintainers.

      Anyway, that is my $.02 cents. Thanks!

      _ _ _ _ _ _ _ _ _ _
      - Jim
      Insert clever comment here...

      Thanks for your reply.

      Up to now, I have not used 'use strict' for the very reasons you cite. Besides that, it appears to slow the script down tremendously (this may be due to the warnings). After I'm done with 'use strict', I am considering commenting the line so the script will load quickly again.

      The script has a difficult to find intermittent defect. So, I'm employing 'use strict' to help find bad habits and maybe even help find this or some other defects.

      I'm a C++ programmer by trade and because of the nature of C++, I try to let the C++ compiler find defects for me as often as possible. In this instance, I'm employing the same approach to Perl.

      Richard

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://194587]
Front-paged by wil
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others exploiting the Monastery: (8)
As of 2014-10-25 18:40 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    For retirement, I am banking on:










    Results (147 votes), past polls