AssetXero has asked for the wisdom of the Perl Monks concerning the following question:

Hello all, I am working on a project that requires dynamic use of various custom modules. I have successfully written a Just-in-Time-Module method that allows me to create module files on disk in my BEGIN and "require" the module and execute its functions further on in my application. With success here, my next step is to find a way to store my module code entirely in RAM - rather than having it create a .pm file on disk. I have tried a couple of things using IO::Scalar and tie but haven't had much success thus far. What I am hoping to do is to have $Mod_Code contain the code of my module while $Mod_Pointer provides a pointer on where to find this within RAM. Any ideas or thoughts would be helpful. Best, AssetXero
  • Comment on Loading PERL Module from scalar in RAM?

Replies are listed 'Best First'.
Re: Loading PERL Module from scalar in RAM?
by kcott (Archbishop) on Apr 16, 2023 at 21:23 UTC

    G'day AssetXero,

    Welcome to the Monastery.

    I was looking into something a few years ago which seems rather similar to what you're after. Take a look at "require() @INC hooks problem". That's a rather long thread; you may gain something from reading it in its entirety; however, if you feel TL;DR setting in, "Re: require() @INC hooks problem [SOLVED]" contains links to the most pertinent parts.

    — Ken

Re: Loading PERL Module from scalar in RAM?
by haukex (Archbishop) on Apr 16, 2023 at 18:34 UTC

    Although I'm having a hard time imagining what you might need this for, and I think it'd be better if you explained that and showed us a SSCCE: use is like BEGIN { require Module; Module->import( LIST ); }, and require is like a do which first checks if the file has already been loaded (via %INC), and do is like a fancy eval. So the answer to your question is likely* eval, although of course that comes with serious security considerations if the code being executed is not 100% under your control.

    * Update: The @INC hook mentioned by the others is certainly a possible solution as well.

Re: Loading PERL Module from scalar in RAM? (@INC hook)
by LanX (Saint) on Apr 16, 2023 at 19:32 UTC
    @INC has a hook mechanism, where you can place a callback instead of a string path.

    The callback can decide to return the code if encountered by require while working thru @INC.

    The interface is a bit convoluted but it works. After adding the hook inside BEGIN you can call use or require deeply hidden inside foreign code and your "RAM modules" are installed.

    quotes from the docs

      You can also insert hooks into the file inclusion system by putting Perl code directly into @INC. Those hooks may be subroutine references, array references or blessed objects. See "require" in perlfunc for details.

    ...

      You can also insert hooks into the import facility by putting Perl code directly into the @INC array. There are three forms of hooks: subroutine references, array references, and blessed objects. ...

    edit

    here some example code from an older discussion

    in that case the code is fetched via HTTP, but it should be easy to to just fill in your RAM stuff instead.

    Cheers Rolf
    (addicted to the 𐍀𐌴𐍂𐌻 Programming Language :)
    Wikisyntax for the Monastery

Re: Loading PERL Module from scalar in RAM?
by dsheroh (Monsignor) on Apr 17, 2023 at 08:29 UTC
    You're overcomplicating this. A module is basically just a hunk of Perl code that makes use of the package keyword. This code can be executed directly from a scalar by using eval:
    ~/src/tmp$ cat dynamod #!/usr/bin/env perl use strict; use warnings; use 5.010; my $mod_source = 'package Foo; sub bar { say q(Hello, world!) }'; eval $mod_source; Foo::bar(); ~/src/tmp$ ./dynamod Hello, world!