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.
| [reply] [d/l] [select] |
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.
In the absence of evidence, opinion is indistinguishable from prejudice.
Suck that fhit
| [reply] [d/l] |
|
package Foo;
our $test = 12345;
package Bar;
print $test;
__END__
12345
| [reply] [d/l] |
|
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: <%-{-{-{-<
| [reply] [d/l] [select] |
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
| [reply] [d/l] |
Re: Is 'use vars' really obsolete?
by LanX (Saint) on Sep 19, 2017 at 01:31 UTC
|
> Am I missing something?
Well we are missing sample code demonstrating your problem.
our has the same scope like my and binds a var-symbol inside that scope to a reference.
See for instance Re: Using hashref values in constant declarations.(binding)
I can't see a case for use vars which can't be solved with our.
| [reply] [d/l] |
|
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: <%-{-{-{-<
| [reply] [d/l] [select] |
|
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). | [reply] [d/l] [select] |
|
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.
| [reply] |
|
|
|
|
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.
| [reply] |
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. | [reply] |
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. | [reply] |