in reply to Re^2: ifdef in modules
in thread ifdef in modules

According to the ifdef docs:

This version is completely written in Perl. It uses a source filter to provide its magic to the script being run and an @INC handler for all of the modules that are loaded otherwise.
which says to me that we use an @INC handler to load modules. And the lib says it puts stuff at the front of the @INC. So it sounds to me like the two are not compatable with each other.

A quick test shows that if you "use ifdef;" at the top of your module, whatever you put on the commandline will propogate... you may want to try more significant tests before relying on it, though.

Replies are listed 'Best First'.
Re^4: ifdef in modules
by clee (Novice) on Jun 14, 2005 at 21:44 UTC

    Ok, it looks like I'll have to read up on how an @INC handler works (suggestions are welcome).

    In the meantime, as per your test, I put 'use ifdef;' at the top of the module, and the vars I pass on the commandline now propagate. Just to make sure I understand the significance of this, let me see if I've got this right:

    1. -Mifdef=DEBUGGING on the commandline puts a handler into @INC
    2. use lib './perl5lib'; in foo.pl puts perl5lib into @INC
    3. use ifdef; in Bar.pm puts another handler into @INC

    The last handler (added in step 3) can now get triggered because it is at the front of @INC. It also knows about perl5lib because it was added in step 2 before the triggered handler. It is also able to process the pod sections tagged with DEBUGGING because it was set in the original handler in step 1.

    Am I even close? All this playing with @INC is pretty new to me, so forgive my ignorance.

    Thanks!

      Ignorance? I'm just figuring this stuff out now, too :-)

      1 - correct. Specifically, at the front of @INC.

      2 - correct. Specifically, at the front of @INC (in front of the handler that ifdef put in)

      2.1 - when the module is loaded, perl looks at @INC, finds perl5lib, finds the file there, loads it, and compiles it. During that compilation, it sees...

      3 - incorrect. It sees the use ifdef, but doesn't reload ifdef (it's already loaded). It does, however, call ifdef->import(). This action turns around, figures out what ifdef parameter was passed on the original commandline (it's stored in an environment variable), and then calls the source filter on your code immediately. Once the source filter is done, perl continues parsing and compiling the rest of your module.

      So, actually, it's not as convoluted as you may have thought. ;-) It does seem very convoluted, though.

        Ah...so I wasn't close at all :)

        Well, your explanation makes sense, thanks. Unfortunately, that still leaves me at an impasse. There's little value in adding 'use ifdef;' to all my modules, since the whole point of my using it is so that sections tagged with DEBUGGING will only activate during development, but be ignored in production, without any changes to the code. With 'use ifdef;' at the top of every module, I'd have to take it out when promoting to production (since production will not have ifdef). I could just as easily take out the debug code itself instead.

        I suppose I could try 'use if $ENV{DEBUGGING}, ifdef;', but it just feels like what seemed like an elegant debugging solution in ifdef now requires too many workarounds.