in reply to Re^2: Module development: concurrent versions (Updated)
in thread Module development: concurrent versions (Updated)

I needed to be able to load both modules concurrently so I can run them on the same array

I tried the following experiment with Math-GMPz (a perl extension):
1) Place version 0.31 of GMPz.pm in ./temp31/Math;
2) Place its GMPz.dll in ./temp31/auto/Math/GMPz;
3) Place version 0.32 of GMPz.pm in ./temp32/Math;
4) Place its GMPz.dll in ./temp32/auto/Math/GMPz;

Then run the following script:
use warnings; use strict; unshift @INC, "temp31"; require "temp31/Math/GMPz.pm"; print $Math::GMPz::VERSION, "\n"; unshift @INC, "temp32"; require "temp32/Math/GMPz.pm"; print $Math::GMPz::VERSION, "\n";
which outputs (as desired):
0.31 0.32
and just goes to prove that one can easily (albeit a bit kludgily) load 2 different versions of the same perl extension into the same script.

You should be able to apply the same technique with Devel::Size.

Cheers,
Rob

UPDATE: However, I note it's not quite so simple if I try to load them in the reverse order (ie first load 0.32, then 0.31):
0.32 Math::GMPz object version 0.32 does not match bootstrap parameter 0.31 + at C:/_32/ap1007/lib/DynaLoader.pm line 224. Compilation failed in require at try.pl line 10.
Not sure why that happens - perhaps some %INC manipulation would counter it.
And, I guess, if you have to keep switching between the 2, then things get even messier.

Replies are listed 'Best First'.
Re^4: Module development: concurrent versions (Updated)
by Anonyrnous Monk (Hermit) on Dec 23, 2010 at 11:44 UTC

    ...but after you've loaded the second version, the variables/subroutines/etc. of the first loaded version will have been overwritten.  IOW, how would you (and Perl) tell apart Devel::Size::total_size() (version 1) from Devel::Size::total_size() (version 2), unless you put them into a different namespace, or name the subs differently?  (At least, it was my impression that BUK wanted to run both routines concurrently, for debugging purposes.)

    Or am I missing something in your approach?

      IOW, how would you (and Perl) tell apart Devel::Size::total_size() (version 1) from Devel::Size::total_size() (version 2)

      Dunno - my impression was that the version 1 output would be put into 1 file, and that the version 2 output into a different file ... and that something like 'diff' would then be a useful tool (because it's the same big array being looked at in both instances, and the problem of differing memory addresses won't arise) ... but I could well be missing something, too.

      Cheers,
      Rob

        You're right that just being able to load both from the same script and run them serially over the same array would meet my immediate needs.

        And in theory, it should be possible to load the same named DLL provided they are in different subdirectories. (Under Windows at least.)

        But forcing Perl to (re)invoke the dynaloader would require messing with %INC between requires I think.


        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.

        Ah, I see what you mean :)  Still, I think it wouldn't work, because the dynamic linker would not remap the same .text/.data symbols that have already been mapped upon initial loading of the lib (at least not on Linux/Unix — maybe Windows is different in this regard).

        (AFAIK, that very property is being used to hijack certain routines (such as in libc) by LD_PRELOADing some other lib that provides the same routines, so that the ones of the same name supplied in a later loaded lib will be ignored.)

        To verify, I just played with this a little, and even by manually fixing the bootstrap version issue you mentioned, clearing various DynaLoader arrays before trying to switch libs

        undef @DynaLoader::dl_modules; undef @DynaLoader::dl_shared_objects; undef @DynaLoader::dl_librefs;

        and manually loading the shared object file

        DynaLoader::dl_load_file('Devel-Size-0.72/blib/arch/auto/Devel/Size/ +Size.so');

        I was not able to get the total_size() XS routine from 0.72 called.  Even after having loaded the new (0.72) Size.so (and I did check with strace that it was in fact loaded), it was still the 0.71 version (loaded/mapped first) that was being called... As expected.

        Anyhow, even if you could get this to work somehow by further messing around with DynaLoader, it would likely not be easier than just using a different namespace.