Re^3: global var
by stevieb (Canon) on Apr 05, 2017 at 21:01 UTC
|
See GotToBTru's post to create a proper example, but from your code, I see this:
# exported functions
That makes me think you copy/pasted something off of the Internet, and with the lines that follow that comment, it appears it closely resembles perl4 code (or someone coding perl5 that hasn't migrated to the perl5 mindset yet. This was nearly two decades ago!).
I feel that you need some new resources to read, research and reflect upon. Is this a project that you were forced into and are trying to adjust by chance? | [reply] [d/l] |
|
| [reply] |
|
use manageusers qw(LoggedOn_user_id);
Software error:
"LoggedOn_user_id" is not exported by the manageusers module
Can't continue after import errors at update_tables-development.cgi line 30
BEGIN failed--compilation aborted at update_tables-development.cgi line 30.
BEGIN {
use vars qw($VERSION @ISA @EXPORT);
use DBI;
# $ENV{DBI_TRACE}=1;
# $ENV{PERL_DBI_DEBUG}=1;
require Exporter;
@ISA = qw(Exporter);
# exported functions
our @EXPORT_OK = qw(
&OpenConnection
&OpenSession
&ProcessLoginRequest
&ProcessLostDataRequest
&LoginUser
&decodeEncryptedPassName
&UpdateUserData
&GetUserLostData
&LogoutUser
&GetUserSessionCookie
&CheckForAuthorizedUser
&Expires
$attempts
$adminaccess
$LoggedOn_user_id <<<<<<----------------------
&Now
&CheckValidLoginChar
&CheckValidEmailChar
&print_md5_javascript);
$VERSION = '0.0.1';
}
| [reply] [d/l] [select] |
|
- use manageusers qw(LoggedOn_user_id);
+ use manageusers qw($LoggedOn_user_id);
perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'
| [reply] [d/l] |
|
|
|
"Don't we all cut and paste from the internet or our own old code or code on CD's that come with textbooks? Yes we do."
No. We don't. Especially stuff from 2003.
Things change rapidly in the tech world. You can not build something for today's world using something that came from over a decade ago, no matter what.
You can not expect something from 2003 to act and behave today like it did then. Even in 2003, the code you've posted was outdated. If you are creating something new, you'll need to get up-to-speed on today's technology. Being an auto-mechanic by trade (but out of the industry for many years), it's like showing an example of a carburetor from a vehicle, while asking for help on a brand new fuel injected, computerized ride. I'm also a licensed residential electrician by trade, and asking about the expansion of aluminum wires in a copper socket in today's world would also be akin.
Help may come, but with 14 year old code, you're pretty much going to be kicking a dead horse (imho).
To further, the code you did post was broken horribly, and wouldn't even compile back then. Even on the node I'm replying to, you still close off with a brace where a parens is required.
| [reply] |
|
|
|
Re^3: global var
by GotToBTru (Prior) on Apr 05, 2017 at 20:55 UTC
|
| [reply] |
Re^3: global var
by Marshall (Canon) on Apr 06, 2017 at 13:27 UTC
|
To clarify (I hope) a few things about "use xxx;"
use xxx; #imports all of the symbols in @EXPORT
use xxx (); #imports none of the symbols in @EXPORT
#this empty list is the same as: (updated)
#BEGIN { require Module }
use xxx qw(OpenConnection $LoggedOn_user_id); # imports
# all of the symbols in @EXPORT AND subroutine OpenConnection
# AND the scalar $LoggedOn_user_id from @EXPORT_OK
Update: Another attempt at explaining "use".
Case 1: A plain use xxx; #imports all of the symbols in @EXPORT.
Case2: use xxx qw(OpenConnection $LoggedOn_user_id); #imports only
the function OpenConnection and the scalar $LoggedOn_user_id. Once
a list (the parens) after the "use" shows up, this has the effect
of making @EXPORT the same as @EXPORT_OK. In other words, the
symbols in @EXPORT are not imported by default and must be explicitly
imported like the symbols in @EXPORT_OK. Any combination of symbols
in @EXPORT or @EXPORT_OK can go in this list after the "use".
Case 3: (consequence of case 2), use xxx (); There is an empty list of stuff to import and nothing is imported - the automatic importing of the @EXPORT list is
"Overridden".
When you import a symbol, you can use the "short" name,
e.g. print $LoggedOn_user_id;. If we "used" the
manageusers module, but did not import $LoggedOn_user_id,
that variable can still be accessed with the fully qualified name,
print $manageusers::LoggedOn_user_id; So if you use
the fully qualified name, the variable or sub name does not
need to be exported (provided that you have used the module to
get it loaded). Only "our" variables can be exported or accessed
from another module. A "my" lexical variable cannot be. "our" puts
the symbol into the package's symbol table - that means among other
things that the fully qualified name is going to work. Such an operation
makes no sense for a lexical scope "my" variable.
File: manageusers.pm
#!/usr/bin/perl
use warnings;
use strict;
package manageusers;
BEGIN {
use vars qw($VERSION @ISA @EXPORT);
use DBI;
# $ENV{DBI_TRACE}=1;
# $ENV{PERL_DBI_DEBUG}=1;
require Exporter;
@ISA = qw(Exporter);
# exported functions
our @EXPORT_OK = qw(
$attempts
$adminaccess
$LoggedOn_user_id
Now
CheckValidLoginChar
CheckValidEmailChar
print_md5_javascript);
$VERSION = '0.0.1';
}
our $LoggedOn_user_id=33;
our $attempts = 99;
1;
File: testManageUsers.pl
#!/usr/bin/perl
use strict;
use warnings;
use manageusers qw($LoggedOn_user_id);
print "$LoggedOn_user_id\n"; #prints 33
print "$manageusers::attempts \n"; #prints 99
#Note that $attempts is NOT <strike>exported</strike> imported,
but still #can be accessed by the fully qualified name!
I hope this helps. Its really early in the morning here, but
I think I did this right. Run my code and then pare further
questions down to just the basics and variables involved.
Corrected "use xx ();" comment. A bit twitchy with the CTL-V this morning. Also changed commend about $attempts in the mail program. Thanks shmem. | [reply] [d/l] [select] |
|
use xxx (); #imports all of the symbols in @EXPORT
use xxx qw(OpenConnection $LoggedOn_user_id); # imports
# all of the symbols in @EXPORT AND subroutine OpenConnection
# AND the scalar $LoggedOn_user_id from @EXPORT_OK
Sorry, but those two are incorrect. As per use, use Foo (); is exactly equivalent to BEGIN { require Foo }, so nothing is exported at all. When you say use Foo qw/bar/;, Exporter exports only that, regardless of what's in @EXPORT.
Update: Hm, my posting seems to have overlapped with an update to the node.
| [reply] [d/l] [select] |
|
Not impressed with EXPORT_OK. Have spent the last 4 hours adding functions to use xxx qw(....)
and screwing lots of things up. Calls to cgi? action invoked functions calls that I then had to ad.
Not worth it??
My underlying problem still remains with one scalar value that will not import.
Yuck!!!
| [reply] |
|
|
|
use xxx; #imports all of the symbols in @EXPORT
use xxx (); #imports all of the symbols in @EXPORT
use xxx qw(OpenConnection $LoggedOn_user_id); # imports
# all of the symbols in @EXPORT AND subroutine OpenConnection
# AND the scalar $LoggedOn_user_id from @EXPORT_OK
[download]
I was originally used the first example and calling all the subs with manageusers::sub
and I guess that is why they worked and the scalars were imported also.
I recently took a fellows advice and changed the export to our EXPORT_OK and am now having to put the called subs by name in use xxx qw(sub1 sub2... sub10) to get those calls working again.
I guess its back to the drawing board on this.
I did read that it is not good to use xxx; as it imports everything into that module, even subs/scalars that are only for other modules.
Anyway thanks for the information and with that clarification I can probably resolve my issues.
Best regards | [reply] [d/l] |
|
imports everything into that module, even subs/scalars
The advice in What_Not_to_Export regarding scalars is this
Do not export variable names. Just because Exporter lets you do that, it does not mean you should.
@EXPORT_OK = qw($svar @avar %hvar); # DON'T!
Exporting variables is not a good idea. They can change under the hood, provoking horrible effects at-a-distance that are too hard to track and to fix. Trust me: they are not worth it.
To provide the capability to set/get class-wide settings, it is best instead to provide accessors as subroutines or class methods instead.
Which is where I think this node started with the problem
$userid = $manageusers::LoggedOn_user_id;
and I think you were on the right path here in eliminating the global variables
I also changed $LoggedOn_user_id to a function call &GetLoggedOn_user_id to deliver the number to the other module and it still does not work.
I think you now know to make it work.
poj
| [reply] [d/l] [select] |
|
Please see my 3rd attempt at explaining this "use" business. One problem with importing all of the @EXPORT stuff by default is that this can cause name conflicts. Also, if a program is large and uses a lot of modules, having an explicit import list can help with figuring out later what module something is in.
Yes, if a variable is an "our" variable, the fully qualified name will work even if that particular symbol is not exported/imported. subs/functions go into the package symbol table in any event. One aspect of this is that there is no such thing as a truly private function in Perl. It is considered very bad form to call some function that is not part of the public interface, but Perl will not stop you from shooting yourself in the foot like that. If you know the function's name, you can call it.
Oh, another point, in the @EXPORT list, you can ditch the leading & character (that's an old Perl 4 artifact). Put "someFunction" instead of "&someFunction".
| [reply] |
|
Checked out the code you suggested and runs exactly as expected.
Looked at my code, made sure exactly the same for the export and use and it failed exactly as before.
Something is blocking the importing of the data through not exporting the $LoggedOn_user_id.
I set the LoggedOn+user_id to a number to test ant did not import.
| [reply] |
|
I am glad that you ran my code and you see that it works.
The manageusers.pm file should have the "our" declaration
of $LoggedON_user_id and this "our" declaration should not appear anywhere else.
I am not sure what your remaining problem is, but I suspect that the solution will be simple once
the problem is fully understood.
Again, try to make a very, very simple example of the problem. Forget the web server for
the moment. Get your script to work from the command line.
Your "cgi" script doesn't even need to import $LoggedON_user_id as long as it does
"use manageusers ();", (which imports nothing), you can still access $manageusers::LoggedON_user_id as long as manageusers.pm has something like
our $LoggedON_user_id = "default";
| [reply] [d/l] |
|
|
|
|
In your original post you wrote 'I have global var in main unit:' and 'In another unit I have: use manageusers;'
What do you mean by 'unit' ?. Do you have the same variable name declared in both the cgi script and the manageuser module something like this
# cgi script
use strict;
our $LoggedOn_user_id = 0;
#
#
#
use manageusers qw($LoggedOn_user_id);
print $LoggedOn_user_id;
# package
package manageusers;
require Exporter;
our @ISA = qw(Exporter);
our @EXPORT_OK = qw( $LoggedOn_user_id );
our $LoggedOn_user_id = 123;
1;
The code prints 0 not 123
poj
| [reply] [d/l] [select] |
|
|
|
|
|
|