Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw

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

by jcb (Parson)
on Mar 22, 2021 at 22:52 UTC ( [id://11130158] : note . print w/replies, xml ) Need Help??

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

As my fellow monks have mentioned, our creates a lexical alias to a global variable. Since you are not using packages, all of your code is ending up (implicitly) in package main.

In the absence of any package statements, our $DEBUG; declares a lexical alias $DEBUG in the current lexical scope for the global variable $main::DEBUG (or $::DEBUG since main has a special alias at the empty name). That global variable still exists for other lexical scopes, which is why your code worked correctly without strict in the sub-scripts.

Note that our declares a lexical alias and optionally sets a value for the aliased global. Using our $DEBUG = 1; both declares the alias I described above and sets $DEBUG to 1. Using only our $DEBUG; only declares the alias and does not change the value at all. Since the alias aliases a global variable, that variable will still have whatever value it was previously given. This is different from my $var, which creates a new and different $var each time it is used. In all cases, a variable that has never been assigned reads as an undefined value.

In brief, since you are not using packages, all you need to do is add "our $DEBUG;" to each of your sub-scripts (and similar lines for other our variables that you want to "import" from the main script). The variables already exist in Perl's symbol table, you only need to create new lexical aliases to them.

Lastly, this also means that if your sub-scripts have any variables that are not used in other files or the main script, you can declare them with my in the sub-script, and each sub-script can have its own variable, even if two sub-scripts have different my variables with the same name.

Replies are listed 'Best First'.
Re^2: How to import "global" variables into sub-scripts from main script?
by AnomalousMonk (Archbishop) on Mar 23, 2021 at 00:08 UTC

    Your explanation++ is very good and clear and may benefit future readers of this thread.

    Unfortunately and for reasons I don't understand, Polyglot cannot use our to declare/alias package globals and also cannot use the fully-qualified form of a package-global variable name to access it. The only solution acceptable to Polyglot is that the behavior of strict be changed so that it may be used in any or all of the constituent text files of the application's source without otherwise altering that source in any way. Again, I don't understand Polyglot's reasoning on this point, but I very much doubt it's likely ever to change.

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

      My reasoning is quite simple: It follows my understanding of the entire purpose of "strict". Its purpose is to guide the programmer into better, more readable coding practice and to alert the programmer to potential code ambiguities, etc. Of itself, strict appears to offer no other benefit in terms of execution efficiency or operation/functionality of the code itself. As long as strict is helpful, by all means use it--and I typically do. But if it is no longer needed or helpful, there is no sin in not using it. Tools are just that: tools--they are there to be used when you need them. If you have a bad leg, use crutches; when the leg is good, you can put them away.

      It might help some here to understand my point of view to know that I have NEVER, and will probably never in the future either, had anyone work together with me on my code aside from the few and relatively minor snippets that I may have put here on perlmonks in questions from time to time. It is a very remote possibility that such will ever occur, because I don't even know anyone who programs in Perl. I know programmers of other languages--but they would shake their heads at Perl and say that they couldn't help me in that department. Essentially, my code is only ever going to be seen, understood, or maintained, by me. Programming is not my bread and butter. I don't think I've ever earned a penny for it beyond the wages I would have received anyhow for work that I chose to augment with a little coding. My mind is, if it functions well and satisfies my needs, great; if it helps, great; if it only hinders, makes life more difficult, etc., discard it.



Re^2: How to import "global" variables into sub-scripts from main script?
by Polyglot (Chaplain) on Mar 23, 2021 at 00:17 UTC

    Obviously, I was a bit frustrated over some things yesterday--had a bit of a bad day. I'm learning. However, my skepticism regarding the benefits of "use strict;" in this context remains. So far, I have seen no benefit at all in adding it to my subscripts: i.e., the only thing it has done is to require the declarations of variables that Perl already knew and was happy with. Strict has, in the absence of these declarations and until they were added, killed the process so that it won't even run, whereas before it would run flawlessly. Adding the global declarations to each and every subscript, when they were already defined in the main script, has only added multiple KB to my files and seemingly for no additional benefit--no additional change in form or function or even feedback on the script quality. I'm left to wonder how much the added kilobytes affect speed/efficiency of code execution, which causes me to seriously wonder if it might not be best to develop under "strict" then remove the added bloat, including the "use strict;" pragma, once everything is running and fine-tuned--including for the main script, as that would save multiple pages of code that appears to be entirely vestigial in terms of the actual script operation (only there for human readability).




      I will just offer: using strictures, I use fatal warnings and all, has saved me hundreds of hours (update: maybe thousands, now that I think about it) of time and qualifying variables has cost me a couple dozen. It has also allowed me to keep several jobs because I shipped magnitudes fewer bugs.

      Being “correct” is a chore. Being “incorrect” frequently ends up a living hell.

      Developing with strict and then removing it should have no effect at runtime, but you would likely be better served using a persistent execution environment or ByteLoader then by worrying about the relatively small parsing overhead of use strict; and our.

      The important feature that strict 'vars' provides is that it enforces declaration of variables, which will catch typos. If you mistype if $DEBUG as if $DEGUB, strict 'vars' will cause an error, while running without strict will cause Perl to silently create a "$DEGUB" variable with an initial undefined value.

      Lastly, while our is equivalent to simply running without strict in terms of making global (package) variables available, my actually does alter the semantics of the program. The only bloat you will get from strict is use strict; itself and any use vars or our declarations — all other variable declarations are actually important.