John M. Dlugosz has asked for the wisdom of the Perl Monks concerning the following question:

Found it: I was passing a list ref to a function that "ate" it, shifting the contents off as it processed. So it only worked the first time it was called.

This affected the export-by-tag feature, and Exporter::VA uses itself, and both M2 and M3 used the ':normal' tag when importing Exporter::VA. So the second time it expanded to nothing.

That does not explain the observation that removing the 3rd call made the second work. Perhaps my early print statements were not clear enough when I first started exploring. Since this is what made me panic (cause should preceed effect!), it underscores the point that good note-taking and observations are essential. However, it's a truism that these things happen late at night when one is almost done implementing a new feature...so it generally doesn't get handled as formally (at first).

—John


Can someone please help me with this? I'm at my wit's end, and it's driving me nuts.

Basically, the code looks like this:

package C1; use M1 v1.0 qw/--verbose_import &foo bar baz quux bazola $ztesch --dum +p/; package C2; use M2 v1.0 qw/ foo baz $ztesch :tag1/; package C3; use M3 v1.0 qw/ --verbose_import foo --dump/; print "so what?\n"; package C4; use M2 v2.3.4.5 qw/foo baz --dump/;
The funny thing is that M3::import is never getting called, if and only if I have the M2 usage both before and after it. If I remove either of those, then M3 works fine.

I tried a simple test case, (files test2.perl, Dummy*.pm) but it did not reproduce the problem. My actual test, with stuff stripped out to make it what I show above, is it test1.perl. All this is posted at http://64.127.185.180/help1.zip (18305 bytes). Would someone take a look at it? Maybe it's just something I'm not seeing and need another pair of eyes.

Thanks,
—John

Update: When run, I expect the M3::import call to report its parameters, then die on foo. It should never get to the C4 usage of M2 (again) or the non-BEGIN stuff. Comment out one of the use M2's and see the difference.

Replies are listed 'Best First'.
Re: import() not getting called. Huh?
by BrowserUk (Patriarch) on Dec 20, 2002 at 10:03 UTC

    I'm not sure if this is helpful or not.

    I installed the testcode on my system, ran test1.perl and the last line of the output was print "so what?\n";. If I read it right, that indicates that everything worked on my system?

    I added these 3 lines to the end of test1.p(er)l

    package main; use Data::Dumper; print Dumper \%INC;

    and you'll see from the end of the output below that indeed, M1, M2 & M3 are all loaded.

    The full output

    The difference (and hopefully a clue) is that I didn't install it using the installer provided, I installed it manually relative to '.' in my %INC. The directory structure I used is

    Let me know if you need any further info about my setup.


    Examine what is said, not who speaks.

      I have a die in the M3::import, so if you got "so what?" it illustrates the problem! Sorry if I wasn't clear last night; it was late and I was frustrated.

      Comment out the last stanza (the second use of M2) and see what happens.

      How can something following me affect my call? It appears that M3::import is not being called if M2 is used both before and after it in the source file (into different packages, though).

      Your trace shows that M3 loaded (print at the end of the file before the 1;), but there is no report that import was called with its parameters. Instead, the next report is that M2 was imported again.

        Sorry. I was mis-interpreting the output, but I tried something else

        I commented out  #Err "NOT IMPLEMENTED YET."; line 183 of VA.pm and ran the following script.

        package C1; use M1 v1.0 qw/&foo bar baz quux bazola $ztesch --dump/; #package C2; use M2 v1.0 qw/ foo baz $ztesch :tag1 --dump/; package C3; use M3 v1.0 qw/foo --dump/; print "so what?\n"; package C4; use M2 v2.3.4.5 qw/foo baz --dump/;

        M3 was imported, but M2 fails with a version check failure, so I replaced the last line above with

        package C4; use M2 v1.0 qw/foo baz --dump/;

        And that gave me identical results. M3 imported, M2 fails?

        Output

        Then I moved the first M2 line below the M3 line; and again M3 imports but the M2 line--that works above it--fails when moved below it?

        Again, I don't know if this helps any, but I thought I'd pass the information along in case it does. If this is another red-herring and you'd prefer not to get any more, just say so and I'll stop:).


        Examine what is said, not who speaks.

Re: import() not getting called. Huh?
by MarkM (Curate) on Dec 20, 2002 at 05:00 UTC

    I spent a good 20 minutes looking at your code (1490 lines of code!). It is excessively complicated for the task that it seems to be accomplishing. Without verifying every line of code, the only thing I can suggest at this point is:

    1. Re-write the code to be easier to read, and much simpler. In particular, the interface should be simpler.
    2. If I had to make a bet, I would say that a global variable, or lexical variable within a closure, is being used or defined incorrectly.

    Sorry I cannot be of more help.

      I've just spent a nice chunk of time looking over this too, and the only interesting result I got was after useing only M1 and M3 the error: NOT IMPLEMENTED YET. at test1.perl line 60 BEGIN failed--compilation aborted at test1.perl line 60. (The line is use M3 ..., in case our line numbers are off.) It appears to be upset at foo, and aborting compilation. What we really need is to step through the BEGIN blocks with the debugger, but I don't even think that's possible. Hopefully that's a helpful clue, John; it's the best I can do.

        That's what's supposed to happen when M3 is used, since it's not implemented yet. I wrote the test code before continuing, so I can test as I go. And found that it's not being tripped if M2 is used both before and after.
      I think you're counting the documentation lines, not the code. The module (with internal comments but not the manual in the attached POD) is under 400 lines.

      I'm sorry you find it excessively complicated. I thought it was elegant and to the point for the task it is documented as accomplishing.

      The interface has been well-received, in fact. See the replies to the original design draft at Module Design strawman - Exporter::VA. If you have any serious suggestions to improve it, I'm all ears.

      —John

        I'm counting lines of *.pm and *.perl. I think the problem I have with your code is that it is very difficult to read. The indenting scheme is extremely odd, and inlined comments do not describe the code flow.

        To me, the idea of modules having fine-grained interface versioning, while cute, is heavy-weight. I prefer simpler modules that provide backwards compatible methods, or are renamed when the functionality or interface is changed substantially enough to require a new interface. The potential for a single module to provide 50 different interfaces to its caller, depending on how it is included, presents a regression testing nightmare in my books.

        If the interface needs to change substantially enough that compatibility methods are insufficient, either the module was not designed properly in the first place, or the module deserves a new name. In either case, the various intermediate interfaces should be obsoleted as soon as possible to prevent confusion.