Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

Is 'use vars' really obsolete?

by jnorden (Novice)
on Sep 18, 2017 at 23:37 UTC ( [id://1199633]=perlquestion: print w/replies, xml ) Need Help??

jnorden has asked for the wisdom of the Perl Monks concerning the following question:

The current documentation for 'vars' says: "...this pragma has been superseded by our declarations,..."

This doesn't seem quite right to me. Consider the following case. Suppose a project is small enough that I want to keep it all in one file. But it is split into two packages, mostly to have separate namespaces for two different tasks. (Maybe one package prints a web form, the other one processes it's submissions.) Now say that I want to 'use strict'. If I declare the the variables with 'our', that defeats the namespace-separating purpose of using packages. Using 'my' would only work if each package was inside its own {block}, making the packages superfluous. Worse, there is no way for packages FOO and BAR to communicate via $FOO::this and $BAR::that if $this and $that are 'my' variables.

I don't see an alternative to 'use vars' for this. Am I missing something?

Replies are listed 'Best First'.
Re: Is 'use vars' really obsolete?
by kcott (Archbishop) on Sep 19, 2017 at 06:11 UTC

    G'day jnorden,

    Welcome to the Monastery.

    The short answer to your title's question, "Is 'use vars' really obsolete?", is no.

    The premise of your question seems to be false (or, at least, faulty): your opening quotation (from vars) says "superseded"; nowhere in that documentation does it say "obsolete".

    You will still find the vars pragma in use. our was introduced in Perl 5.6.0 (see "perl56delta: "our" declarations"). Legacy Perl code written prior to that version would not have had our available; modules aiming for backwards-compatibility with versions earlier than 5.6.0 might use vars. You may well encounter the vars pragma and, as such, you should know about it; however, except in very special cases (such as those cited) you should not use it in new code.

    Here's more of that quotation from vars (emphasising the points I've made):

    "... the functionality provided by this pragma has been superseded by our declarations, available in Perl v5.6.0 or later, and use of this pragma is discouraged."

    Your description of a scenario in which you "don't see an alternative" is unclear. What sort of project is this? What sort of file is it? Why would project size result in a desire for just one file? Is this single file executable? Is the project actually a component of some larger project? I have other questions like those because, as it stands, I'm unable to visualise the code you've attempted to describe.

    Please read "SSCCE" and "How do I post a question effectively?". As others have mentioned, a coded example will help to clarify what you mean: it will also allow us to suggest alternatives, which currently allude you.

    — Ken

Re: Is 'use vars' really obsolete?
by BrowserUk (Patriarch) on Sep 18, 2017 at 23:47 UTC
    Am I missing something?

    Does this help?

    package Foo; our $test = 12345; package Bar; print $Foo::test; $Foo::test='abcde'; package Foo; print $test;; 12345 abcde

    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority". The enemy of (IT) success is complexity.
    In the absence of evidence, opinion is indistinguishable from prejudice. Suck that fhit
      package Foo; our $test = 12345; package Bar; print $test; __END__ 12345

        our has lexical scope.

        c:\@Work\Perl\monks>perl -wMstrict -le "{ package Foo; our $test = 12345; } ;; { package Bar; print 'fully qualified: ', $Foo::test; } " fully qualified: 12345
        Try the statement
            print 'unqualified: ', $test;
        in package Bar.

        BTW: Perl 5.14 introduced the neater (IMHO)  package NAMESPACE BLOCK syntax, so the code above could now look like

        package Foo { our $test = 12345; } package Bar { print 'fully qualified: ', $Foo::test; }

        Update: Note that package also has lexical scope!


        Give a man a fish:  <%-{-{-{-<

Re: Is 'use vars' really obsolete?
by swl (Parson) on Sep 18, 2017 at 23:45 UTC

    If I understand your question correctly, what you are asking for is exactly what our provides. You just need to use a fully qualified name when outside the package.

    See the first example in the docs: https://perldoc.perl.org/functions/our.html

Re: Is 'use vars' really obsolete?
by LanX (Saint) on Sep 19, 2017 at 01:31 UTC
      I can't see a case for use vars which can't be solved with our.

      And indeed, solved better, because our operates within a well-defined lexical scope rather than the (can we say global?) scope of a package namespace. I, too, would be curious to see an example of use vars that jnorden would assert would do something that lexical our and my could not do better (WRT variable names, that is).


      Give a man a fish:  <%-{-{-{-<

      I ran into a case in a module where I had 'use vars' and I changed it to 'our' causing it to break.

      It was in an export module that exports a variable to the caller's package. I had:

      my $code = 'package '.$pkgnam.'; use vars qw($'.$varname.'); $'.$varname.' = "'.$value.'"; '; eval $code; $@ and die "Error in exporting var $varname: $@";
      and had changed it to:
      my $code = 'package ' . $pkgnam . '; our $'.$varname.' = "'.$value.'"'; eval $code; $@ and die "Error in exporting var $varname: $@";
      As a sample varname, I had 'Tor_mgr' being exported back to the using prog. After the change, in the using prog, I got:
      Variable "$Tor_mgr" is not imported at ./rss_rdr line 724. Variable "$Tor_mgr" is not imported at ./rss_rdr line 736. Variable "$Tor_mgr" is not imported at ./rss_rdr line 745. Global symbol "$Tor_mgr" requires explicit package name at ./rss_rdr l +ine 724. Global symbol "$Tor_mgr" requires explicit package name at ./rss_rdr l +ine 736. Global symbol "$Tor_mgr" requires explicit package name at ./rss_rdr l +ine 745. BEGIN not safe after errors--compilation aborted at ./rss_rdr line 754 +.
      What I think was happening, is that the processing of the module didn't happen until after the prog had already been through the 'BEGIN' stage, so this module couldn't insert the 'our' definition in the package's namespace before its usage, so in the 2nd pass, perl saw $Tor_mgr which it now new to be defined later on, but didn't see it in an EXPORT array in the used module (I'm guessing). Anyway, since the 'use vars' was in the first version, that defined it in a non-lexical scope, which passes the 2nd pass's checks.

      It may be that the module could be rewritten to not need use vars, but it doesn't look straight forward.

      FWIW, the module being used, exported variable names with values corresponding to found paths of their lower-case names as executables, so any EXPORT list would be variable per usage (though fixed per program invocation).

        That's lots of voodoo. ..

        the effect of our will be restricted to the eval, I'm not sure how far use vars go.

        I'd say it's globally effective whenever the same package is chosen.

        (but I'm not really trying to understand what is happening during an export here. :)

        edit

        OK I think I have an idea what is happening here and I think the author should have a look into Exporter, IIRC exporting package-vars is part of the specification.

        Cheers Rolf
        (addicted to the Perl Programming Language and ☆☆☆☆ :)
        Je suis Charlie!

Re: Is 'use vars' really obsolete?
by ikegami (Patriarch) on Sep 19, 2017 at 17:09 UTC

    If putting the package in a block "makes the package superfluous", I'm not sure why you're using a package.

Re: Is 'use vars' really obsolete?
by Anonymous Monk on Sep 19, 2017 at 06:19 UTC
    so much stuff in Perl has lexical scope nowadays that you should put each package in its own block anyway, and that takes care of the "our" problem too.
Re: Is 'use vars' really obsolete?
by Anonymous Monk on Sep 19, 2017 at 13:11 UTC
    Strongly agree with the preceding Anonymous post. Put different packages in different files no matter how large or small they are. (After all, now you always know where it is!) It is also a good idea to provide functions in a package to manipulate variables in that package, if only to document (within the package) that the value is used elsewhere. Some pragmas and constructs exist because someone needed them at the time, not because they represent the most-maintable way to write code, especially in a large project. Also, insofar as possible, try to continue a project so that it consistently does things in one way throughout. It is much harder to maintain code that does the same thing in two ways, old and new.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1199633]
Approved by davido
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having a coffee break in the Monastery: (8)
As of 2024-04-19 08:57 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found