http://qs321.pair.com?node_id=551236

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

I'm writing C code that that calls perl. The perl code is in the form of a .pm that will be installed in the usual way. The approach I have taken is to call load_module something like:
load_module(PERL_LOADMOD_NOIMPORT, newSVpvn("My::Module", 10), newSVnv(0.01));
I follow this by pushing the module name onto the stack and instantiating an object by calling call_method("new", G_SCALAR));

I then push the resulting object and some args onto the stack and invoke call_method on the method name. It seems to necessary to call perl_parse, so I do, passing in "/dev/null" as the file name.

char *theArgv[] = { "", "/dev/null" }; perl_parse(my_perl, xs_init, 2, theArgv, (char **) NULL);
All this actually seems to work pretty swell, but I've encountered one difficulty. Any diagnostics originating in the perl code, e.g. "warn"s, etc., give bogus file and line numbers presumably because, having been pulled in via the load_module call, the code was never parsed:

Bad data at /dev/null line 0

I'd like to use the load_module mechanism and yet have the perl interpretter informed of code, for diagnostic reference.

[I can post more code, if helpful. But the actual code is on an isolated host, inaccessible by network.]

Any ideas?

Replies are listed 'Best First'.
Re: Embed: Using load_module
by ioannis (Abbot) on May 23, 2006 at 22:10 UTC
    Normally, you can inform perl to change its notion of line count by writing special comments:
    #line 55 warn ;
    The '#line 55' comment informs perl that the next line shall be number 55; thus, because the input numbers have now changed, the output of this code is Warning: something's wrong at try.pl line 55. . Is this what you are looking for?
Re: Embed: Using load_module
by BrowserUk (Patriarch) on May 23, 2006 at 23:13 UTC

    In addition to setting the line number as explained by joannis above, you can also set the filename using the same comment.

    #line 1 "yourfile.pm"

    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
      Thanks all replicants:

      Firstly, I apologize; I seem to have lied in my original post. I am not using 'warn' but rather 'carp' in the perl module. The 'warn' function honors the '#line <NUM>' comment (and BrowserUk's '#file <NAME>' as well) just fine.

      Of course, being a DRY kinda guy, I'd rather not have to keep these directives synced with the *actual* line number and name. I tried putting a:

      # line 1

      at the top of the page, but apparently, intervening comment lines are not counted, so that the value it winds up using is a bit higher up in the file that it really is. At any rate, I'm using Carp in the module and it does *not* honor these directives.

      What I was really fishing for was a way to use load_module(), allowing the interpreter to search for and load the module in the expected way (have cake) and yet benefit from having used perl_parse()(eat cake). I poked around in the interpreter code a little, wondering if there was a clean way to, perhaps, steal the file name that load_module() determined, but was not obvious to me how I might do that. [please do pardon my parenthetical americanisms].

      Another long shot I tried was to push the arguments to the function of interest onto the stack and then call eval_pv() with *no* parameters, hoping the function would find it's parms waiting for it on the stack. But this did not produce the desired effect.

Re: Embed: Using load_module
by polettix (Vicar) on May 24, 2006 at 10:10 UTC
    Does My::Module use Carp? Consider a simple module (Example.pm):
    package Example; use strict; use warnings; use Carp; sub with_warn { warn "inside with_warn"; return; } sub with_carp { carp "inside with_carp"; return; } 1;
    and a script using it:
    #!/usr/bin/perl use strict; use warnings; use Example; Example::with_warn(); Example::with_carp(); warn "inside main script";
    We get:
    inside with_warn at Example.pm line 5. inside with_carp at /path/to/warn_carp.pl line 7 inside main script at /path/to/warn_carp.pl line 8.
    The second warn is issued by the module, but the perspective is that of the original caller. Of course, I could be totally missing the differences with respect the embedding world.

    Flavio
    perl -ple'$_=reverse' <<<ti.xittelop@oivalf

    Don't fool yourself.
      As you may see in my reply above, I am indeed using Carp. The problem is that I have succeeded in executing a file of code in a such a way that the interpretter has no knowledge of it's textual/source context, e.g. line numbers and file names, etc.

      I often succeed in doing things like that. A dubious gift, that.