use or require?

Ovid on 2007-08-13T08:30:27

Last night, in working with Devel::Recreate (suggest a better module name, please!), I discovered that it's devilishly difficult to differentiate between use and require or capture import lists. After discussions with Andy Armstrong, the only thing I could think of is either coderefs in @INC or overriding *CORE::GLOBAL::require. I can't tell if either solution allows me to differentiate between the use and require. The only thing I could think of is that use is basically this:

BEGIN { require Module; import Module LIST; }

In other words, if require is triggered, I could use HookLexWrap to wrap the import statement (considering inheritance, of course) to fetch the import list. I'd also have to write some XS code to try and grab PL_beginav to find out if the require happened in the BEGIN phase. Thus, the following would be considered a use statement:

BEGIN {
    require Some::Module;
    Some::Module->import(@args);
}

Naturally, this is all very rickety. Is there a better way to do this?


Naming

Aristotle on 2007-08-13T12:19:12

First of all, “Devel::” is reserved for things to be loaded using perl’s -d flag. (It should have been a more specific namespace, really, so people wouldn’t be tempted to dump random junk in there that has nothing to do with -d, maybe DB::Custom:: or something.)

Also, “Devel::Recreate” gives no indication whatsoever about what it recreates. That would be a package, which suggests that the right TLNS for your module is “Package::”.

Now, what does it do with a package? It “recreates”… what exactly? It doesn’t actually recreate anything! In fact, it seems like the name was the source of Ben’s confusion about its purpose. What it does is more like a dumper, but for code, not data.

That suggests “Package::CodeDumper”.

Another choice could be “Package::SourceDumper”, but I almost dislike that one because it vaguely suggests that it dumps the original source, not the code that’s actually in memory.

Re:Naming

Ovid on 2007-08-13T12:24:28

I knew I could count on you to smack me around. Thanks :)

Re:Naming

Aristotle on 2007-08-13T12:46:27

Oh dear, on re-read, that comment sounds a little more vigorous than I intended. :-) Sorry. Wasn’t meant to be slap-around. I know most people find naming much harder and more tedious than I do.

Re:Naming

Ovid on 2007-08-13T13:00:08

Aristotle, I was kidding and I took no issue with what you had to say :)

Re:Naming

gizmo_mathboy on 2007-08-13T20:04:07

Maybe, Package::OpCodeDumper?

Then again, it isn't the opcodes, at least from my weak grasp of the internals, is it?

Re:Naming

Ovid on 2007-08-13T20:26:56

Nope. Not trying to dump opcodes, though I may be forced to dig into them at some point. Just trying to dump what perl thinks the source code looks like.

Re: Solving the wrong problem?

Eric Wilhelm on 2007-08-14T09:08:38

Isn't this about dumping how much of the module exists when it dies during load? Seems like caller() from a $SIG{__DIE__} hook and a line number would suffice. What am I missing? Are you trying to get valid perl output, or just information?

To really do it right, I think you end up source filtering (PPI?) everything (unshift(@INC, sub {...})) into s-expressions or something. I've always wished perl were more introspective, but it seems like syntax is the enemy of introspection (and I really like syntax, so I haven't pursued lisp deeply enough to know if that's really the case.)