Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

Qualified package variable access

by jerryhone (Sexton)
on Dec 17, 2020 at 17:39 UTC ( [id://11125350]=perlquestion: print w/replies, xml ) Need Help??

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

Brothers...any help to identify what I'm doing wrong would be greatly appreciated... I'm putting together some Perl scripts that all connect to an Oracle database. I've put the database connectivity in a library file although I'm leaving each script's specific SQL in the script itself. In my library file (ECClib.pm) I have
package ECClib; my $dbh; sub initialise(){ . . $dbh = db_connect($dbuser, $dbpasswd, $dbserver); . . )
That's all fine and dandy, and I seem to get a good database connection. However, if I then try to use $ECClib::dbh in my parent script, it fails. My calling script has
use ECClib; ECClib::initialise(); my $sql="select InputID from ECCInput order by InputID"; my $sth = $ECClib::dbh->prepare($sql);
The statement handle assignment fails - debugging shows that $ECClib::dbh is undefined. What am I doing wrong?

Replies are listed 'Best First'.
Re: Qualified package variable access
by choroba (Cardinal) on Dec 17, 2020 at 17:45 UTC
    Lexical variables, i.e. the ones declared with my, can't be accessed from the outer scope. You need to use our if you want to access the variable from a different file.

    Another possibility is to declare a closure that exposes the variable:

    package ECClib; my $dbh; sub dbh { $dbh } sub initialise { ...
    use ECClib; ECClib::initialise(); my $dbh = ECClib::dbh();
    map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
      > Lexical variables, i.e. the ones declared with my,

      Tangential:

      I think we should stop calling my variables "lexical", but rather "private".

      It's easier to understand for newbies and less confusing, since "package" vars declared with our are lexically scoped too (well the short non-qualified alias is lexically scoped)

      Not a critic at you more a general meditation.

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery

        I think we should stop calling my variables "lexical", but rather "private".

        Whatever the intrinsic merits of calling them "lexical", we certainly should not call them "private" because that has an established, widely understood meaning which is different from what these variables are. I refer to private members of classes in OO languages such as C++ and Java.

        In fact, "lexical" is a very good name for these variables, because the scope (that is, visibility) and lifetime* are both determined by the static lexical context of the code. You can read the code and know exactly where the variable can be seen and used.

        * Of course, both of these things can be "escaped" through references; that's beside the point.

        I reckon we are the only monastery ever to have a dungeon stuffed with 16,000 zombies.

        At the risk of starting a semantic flame war, I have to say that I personally prefer "lexical" because it is a better description of their actual scope -- from the point of specification to the enclosing right curly (or the end of the file).

        If you search "private variable" you get things that are much more widely visible than Perl "my" variables (e.g. Java private attributes). I worry that a newbie coming from such a background may be confused by the use of "private" into misunderstanding the actual scope of the variable.

        Package variables are in fact not lexically scoped, though the ability to access them by their unqualified name can be. Even if you turn on warnings, you can still access them outside the scope of the "our" by fully-qualifying their names. Consider the behavior of the following one-liners:

        perl -E '{ our $foo = 42; } say $foo'

        perl -Mstrict -Mwarnings -E '{ our $foo = 42; } say $main::foo'

        Perl is a large, complex language, and we need to provide ways to help newbies find a way in. My concern with s/lexical/private/g is that it may teach newbies things they have to unlearn to progress.

Re: Qualified package variable access
by LanX (Saint) on Dec 17, 2020 at 17:44 UTC
Re: Qualified package variable access
by jszinger (Scribe) on Dec 17, 2020 at 18:36 UTC

    When I do this sort of thing, I return the dbh back to the caller, as follows:

    package ECClib; my $dbh; sub initialise(){ . . $dbh = db_connect($dbuser, $dbpasswd, $dbserver); . . return $dbh )
    and
    use ECClib; my $dbh = ECClib::initialise(); my $sql="select InputID from ECCInput order by InputID"; my $sth = $dbh->prepare($sql);

      Better yet:

      package ECClib; my $dbh; sub get_dbh { $dbh ||= db_connect( $dbuser, $dbpasswd, $dbserver ); }

      And:

      use ECClib; { my $dbh = ECClib->get_dbh; ...; } { my $dbh = ECClib->get_dbh; # gets the same instance! ...; }

      If you're using Perl 5.10+:

      package ECClib; use v5.10; sub get_dbh { state $dbh = db_connect( $dbuser, $dbpasswd, $dbserver ); }
Re: Qualified package variable access
by jerryhone (Sexton) on Dec 17, 2020 at 18:38 UTC
    Thanks Brother Rolf. 'our' is the fix. I've been using Perl on and off for 20 odd years and that's the first time I've used 'our' as far as I recall. My very well thumbed O'Reilly camel book (2nd edition 1996!) doesn't actually mention it!
      that's the first time I've used 'our' as far as I recall. My very well thumbed O'Reilly camel book (2nd edition 1996!) doesn't actually mention it!

      our was added in Perl 5.6, released in March 2000. Before that, one of the ways "predeclare" package variables was the vars pragma. You might be interested in the 4th edition Camel, or Modern Perl.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others scrutinizing the Monastery: (4)
As of 2024-04-25 18:12 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found