http://qs321.pair.com?node_id=11130086


in reply to Re: How to import "global" variables into sub-scripts from main script?
in thread How to import "global" variables into sub-scripts from main script?

I appreciate the prompt response, thank you.

So, is there really no way to import the variables from the main script? I thought perl was supposed to be good at passing variables.

I don't have a script named "main". I have no idea what perl would think if I tried $main::DEBUG. Is that supposed to "import" the $DEBUG variable? Would I need to do something more like this:  $MyPerlScript.pl::DEBUG? That just looks tacky and ugly, in my opinion.

It makes no sense to me that the error message would complain about a variable not having been imported--if in fact it's not possible to "import" a variable in the first place. That's the part that gets me, I guess.

Blessings,

~Polyglot~

Replies are listed 'Best First'.
Re^3: How to import "global" variables into sub-scripts from main script?
by choroba (Cardinal) on Mar 22, 2021 at 09:52 UTC
    > I don't have a script named "main"

    But you have a package called "main" (unless you declare a package in your main script).

    If you have no idea what Perl would do, try it. You already know how to create a Perl script and run it.

    > That just looks tacky and ugly

    Yes, it looks ugly, because it is ugly.

    Note that Variable "$x" is not imported is not an error, it's a warning. It's explained in perldiag:

    (S misc) With "use strict" in effect, you referred to a global variable that you apparently thought was imported from another module, because something else of the same name (usually a subroutine) is exported by that module. It usually means you put the wrong funny character on the front of your variable.

    Which doesn't seem helpful, so your confusion is understandable. It seems the explanation needs an addition (volunteers?)

    Update: The required sub-scripts should have failed to compile under strict. If you're using do instead of require, you should check $@ and $!.

    map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]

      Update: The required sub-scripts should have failed to compile under strict. If you're using do instead of require, you should check $@ and $!.

      Remember, I wasn't using strict in the sub-files before. I had assumed that when I said "use strict;" in the main file, and then was bringing in the other subroutines via "require subfile.pl;" that the "strict" had applied to the entire global context. Remember, the global variables are all correctly shared among the files--so why wouldn't strict be shared, too?

      In any case, I had no issues compiling until I added "strict" to the sub-file.

      I'm not using "do" anywhere in the entire script at this point.

      Blessings,

      ~Polyglot~

        > why wouldn't strict be shared

        It would make using any non-strict module from a strict script impossible.

        map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
        the global variables are all correctly shared among the files--so why wouldn't strict be shared, too?

        Because strict, warnings, and many other pragmas have a lexical scope. If used at the very top of the file, their scope is limited to that file. do, require, and use create a new lexical scope for the files they execute. Only evaled code inherits the strict and other pragmas from the surrounding lexical scope.

      Well, since you say it's only a warning--not a show stopper, I tried this at the top of that file:

      our $DEBUG = $DEBUG || 0;

      It didn't work. I still get a whole slew of $DEBUG related errors in the log. So much for attempting to declare them and just take the first error on the chin to save the rest.

      Strict will just have to go this time...it seems to oppose all of what caused me to fall in love with Perl in the first place. I was sick of all the constraints of Pascal, and the strict types...and Perl just seemed to know when something should be a number, or a string, etc. without needing tedious conversion routines or such a strict (strait-jacket) approach.

      Blessings,

      ~Polyglot~

        > It didn't work

        our $DEBUG;
        could have worked, though.

        map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
Re^3: How to import "global" variables into sub-scripts from main script?
by AnomalousMonk (Archbishop) on Mar 22, 2021 at 10:46 UTC
    I don't have a script named "main".

    main is the default package if no package statement has declared any other.

    I have no idea what perl would think if I tried $main::DEBUG.

    This is the "fully qualified" form of a package-global name. It is always valid. Even under strict, fully-qualified package globals can always be accessed with or without pre-declaration. Some examples:

    Win8 Strawberry 5.30.3.1 (64) Mon 03/22/2021 6:33:58 C:\@Work\Perl\monks >perl use strict; use warnings; package Bar { # package-globals can always be accessed in fully-qualified form $main::foo = "hi, i'm assigning this in " . __PACKAGE__ . "\n"; } print "A: this is being printed from default package ", __PACKAGE__, " +\n"; # global $foo not yet declared in main: must access fully-qualified print "B: i'm accessing this from ", __PACKAGE__, ": $main::foo"; our $foo; # declare global $foo in package main print "C: i'm accessing this from ", __PACKAGE__, ": $foo"; ^Z A: this is being printed from default package main B: i'm accessing this from main: hi, i'm assigning this in Bar C: i'm accessing this from main: hi, i'm assigning this in Bar


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

      Keep in mind that I have only one file among all of them which uses the shebang line--just the main script. These attached files are not designed to be independent, and could probably work just as well given a ".txt" suffix. Though I have put ".pl" as their suffix, I do not set their executable bits on the server, i.e. they are chmod 640 instead of 755 (running on linux). Furthermore, they basically return true immediately, without executing anything. All they do is provide space for me to organize my various subroutines.

      Taken together, they average over 850 lines per file. I'd like to bring that down further, as anything over about 600 lines begins to get unwieldy for me and I have a harder time finding things or remembering where to look for them. I never realized that perl wants to be an all-in-one-big-file script, with no way to share global variables!

      Again, I'm not writing or using packages. I'm just spreading out my script into multiple files for organizational purposes.

      Next, I suppose, I'll have to write a separate script that combines all of my individual files into a single file on the server prior to run-time. Sigh. Wow. I can't believe this. I always imagined Perl to be more capable--this seems such a simple thing to be able to do, not even a majorly complex problem.

      Blessings,

      ~Polyglot~

        ... this seems such a simple thing to be able to do, not even a majorly complex problem.

        It is simple, but there's nothing so simple that it cannot be made more complex. :)

        IIUC, you're not using package anywhere, so all your code is in the default main package. But for some reason you can't use the fully-qualified $main::variable_name (with $ replaced by the appropriate sigil) form to access globals, nor can you use
            our $variable_name;
        statements to declare variables within the file-scopes of the various source files of your application.

        I think you're right: avoid strict and warnings like the plague, and use the unqualified form for all globals. If nothing else, it will be employment insurance.


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

Re^3: How to import "global" variables into sub-scripts from main script?
by marto (Cardinal) on Mar 22, 2021 at 09:43 UTC

      Variable "%s" is not imported%s

      (S misc) With "use strict" in effect, you referred to a global variable that you apparently thought was imported from another module, because something else of the same name (usually a subroutine) is exported by that module. It usually means you put the wrong funny character on the front of your variable.

      I did run across that one earlier in my quest for a resolution, but found it of no use to me--too esoteric and short on detail. I have no idea what the "right" "funny character" should be--or even what a "funny character" is supposed to refer to--the dollar sign, perhaps? What else would one prefix a scalar variable with?

      I guess there's no easy answer. Best, in my case, might be just to turn "strict" back off and continue my troubleshooting without its bungling "help." Sorry to have troubled the waters here for nothing.

      Blessings,

      ~Polyglot~

        "What else would one prefix a scalar variable with?"

        It doesn't have to be a scalar, it could be something else, for example a hash, so the character before the variable name would be different. For what it's worth I agree this part of the documentation could do with some work to make things clearer.