in reply to Re^2: detecting an undefined variable
in thread detecting an undefined variable

Thanks for all the replies to my "detecting an undefined ..". I agree with the last reply, that I meant "declared" rather than "defined". It's not clear to me why what I'm trying to do should be so undisciplined (ill advised?). I often put together pieces of code from various places. So it's handy to check whether some variable already exists in another piece. In the example I gave, the code would be in a function being called from some other code, written at a different time. If I had then used a variable called $scale, it would be handy to know whether that variable existed in the calling code or whether I now had to declare and define it anew. If it existed before, I would want to use the existing value. If not, I would define it as
my $scale = 1;
That doesn't seem so undisciplined to me.

Replies are listed 'Best First'.
Re^4: detecting an undefined variable
by LanX (Saint) on Sep 21, 2019 at 17:02 UTC
    > That doesn't seem so undisciplined to me.

    It's fragile and opens the door to many hard to debug potential problems.

    Though most people were interpreting your intention as trying to use $$symbolic dereference. That's why I asked for more context.

    Using hashes for optional values is a common pattern.

    > I often put together pieces of code from various places.

    Well, the common pattern for that class of problems is to use modules with stable APIs.

    If you really want to do code generation by composing code chunks, then consider using package declarations and inspecting an our $scale variable in the STASH

    use strict; use warnings; package Chunk; #our $scale =42; package main; my $myscale = $Chunk::{scale} // 1; print $myscale;

    but now that you use packages you're only one step away of using modules ...

    HTH! :)

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

      Rolf: I appreciate the detailed response. I have tried to use both packages and modules from time to time, but I cannot remember the details of how to do things with either, so I tend to stick to what I can remember. I do use both 'strict' and 'my', but have not figured out how to use 'our' effectively. Actually, I described the history backwards of the calling and the called. Typically, the function in question would be written long before the calling code and would, in fact, end up being called by many different bits of code. Some might define $scale one way, some another, and some not at all. I like the eval() solution and will go with that. Thanks to all.

        From this:

        If I had then used a variable called $scale, it would be handy to know whether that variable existed in the calling code or whether I now had to declare and define it anew.
        If I correctly understand what you're getting at, that's what strict is for, and it'll tell you that real fast! If a package variable is not in scope at a point in your code or does not exist at all, you must then declare or define it, respectively, e.g. with our. If a lexical does not exist, you must define it (and usually initialize it) with my in that scope.

        Typically, the function in question would be written long before the calling code and would, in fact, end up being called by many different bits of code. Some might define $scale one way, some another, and some not at all.

        This sounds like you are creating a hodge-podge of global variables. If so, you are building a nightmare for yourself. Best practice generally dictates that variables, insofar as possible, should be lexical and have as limited a scope as possible | is reasonable. (Constants are another story; you can go crazy with constants!) Ideally, a function should access variables only as arguments passed to the function and never as external variables; thereby, it doesn't matter where or when the function was defined or from where it's called. Of course, it's not always possible to follow best practices and write ideal code, but my (bitter!) experience is that one should immediately question one's motives whenever one is tempted to stray from the Straight Path and indulge unclean practices.

        Update: ... as limited a scope as possible. Having read GrandFather's reply, I think "reasonable" is the better word here.


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