Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

why package definition order affect the available of package variable

by fanasy (Sexton)
on Oct 20, 2019 at 10:06 UTC ( [id://11107717]=perlquestion: print w/replies, xml ) Need Help??

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

I can get the $testBegin::global but I cannot get the $testEnd::global
my question is that
it seems the test package definition location is the key for this issue.
how perl consider the different order ? why perl can call testEnd::show_me() in main but can't see the $testEnd::global in main ?
there is the code :

#!/usr/bin/perl use feature qw/say/; use Data::Dumper; package testBegin { $global = "I'm in the testBegin package global version"; sub show_me { print "$tag: testBegin package $global\n"; } } testBegin::show_me(); print "-"x60; print "\n"; testEnd::show_me(); package testEnd { $global = "I'm in the testEnd package global version"; sub show_me { print "$tag: testEnd package $global\n"; } }

output:
: testBegin package I'm in the testBegin package global version
------------------------------------------------------------
: testEnd package

  • Comment on why package definition order affect the available of package variable
  • Download Code

Replies are listed 'Best First'.
Re: why package definition order affect the available of package variable
by haukex (Archbishop) on Oct 20, 2019 at 10:16 UTC

    The package statement doesn't affect execution order: $global = "I'm in the testEnd package global version"; is executed after the testEnd::show_me() call, so $testEnd::global is still undef at that point in time.

    Note that you should always Use strict and warnings.

      thanks for your quick answer.
      that's the point.

Re: why package definition order affect the available of package variable
by rjt (Curate) on Oct 20, 2019 at 11:56 UTC

    The package { ... } part is actually irrelevant. You can reproduce this behavior with a much simpler script, which might illustrate the issue more clearly:

    say_foo(); my $foo = 'foo'; say_foo(); sub say_foo { say '$foo = ' . ($foo // '(undef)') } __END__ $foo = (undef) $foo = foo

    At the first say_foo() call, the line my $foo = 'foo' has not been executed yet. Simple enough, but now you may be wondering why you're able to call say_foo() at all at that point in the script. The short answer is, forward definitions (and declarations) are a language feature. Otherwise it would be more difficult to have circular subs (a() calls b() and b() calls a(), possibly with even more complex indirection).

    To really drive the point home, it might be helpful to look at how BEGIN { ... } works. BEGIN will run the code in its enclosed BLOCK as soon as it is completely defined, so you can do something like this:

    say_foo(); my $foo; BEGIN { $foo = 'foo' } say_foo(); sub say_foo { say '$foo = ' . ($foo // '(undef)') } __END__ $foo = foo $foo = foo

    Consider this to be illustrative, not necessarily prescriptive. BEGIN is great, but it's not always the best tool for the job. It depends on the situation (and so I'd be happy to dive a little deeper if you want to go into more detail on what you're trying to do). I typically keep my globals at the top (and of course only using globals when necessary), and separating packages out into their own source files, and so I hardly ever (never?) need BEGIN for this sort of thing.

    use strict; use warnings; omitted for brevity.

      Hi rjt ,

      your example code and explain is really good for me.
      BTW, is there any document or guide to let me can look into more deep like yours
      sorry, I want to know more and deep to improve my knowledge of perl
      why package {} is irrelevant ? which else language feature such as forward definitions ?
      thanks a lot!

        Glad I could help. The perlmod Perl documentation is probably the best single source of information on your question. It does talk about package semantics, but pay particular attention to the "BEGIN, UNITCHECK, CHECK, INIT and END" section. In addition to describing things well, it has a really great example which is basically a more complex version of the example I gave earlier.

        why package {} is irrelevant ? which else language feature such as forward definitions ?

        package { ... } is irrelevant to your example because the only thing that matters in your example is the order in which the variable was assigned versus where the variable was used.

        As for language features, Perl is full of them. Perl is an extremely powerful language with a rich history. While there are some specific features that can be enabled or disabled, there are of course many, many more that are simply part of the language. You won't find a comprehensive list of them in one place, that I know of. To learn these features, just keep learning Perl! Keep writing code, keep giving yourself increasingly challenging projects, and look at as many good examples of Perl code you can find.1 Use the excellent Perl documentation every time you aren't sure of something (or browse a random Perl document on a topic that interests you), and you'll usually come away with an answer to your immediate question plus three or four other things you didn't know either. Read Perl books. Visit PerlMonks often, ask questions,2 be a part of the community, and you'll master the language quickly.

        ______________
        1. Look at the source for core modules (find them on your system with perl -V and look for a .../perl/5.xx directory in the @INC section). Also browse MetaCPAN, find a popular module, and click the "Source" link. Just be aware that while most CPAN source is quite good, the quality of CPAN source code does vary from amazing to highly questionable. However, you will see different ways of doing things, and learning to identify good and bad code is an essential skill for any programmer. This will also help you to not re-invent the wheel, as Perl has a huge ecosystem of modules already. While learning, though, re-invent as many wheels as you like. :-)
        2. Ask questions, and also answer some when you can! One of the best ways to learn anything is to force yourself to find a way to explain it to someone else.

Log In?
Username:
Password:

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

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

    No recent polls found