Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

Re: version based compilation

by robin (Chaplain)
on Dec 29, 2001 at 20:32 UTC ( [id://135118]=note: print w/replies, xml ) Need Help??


in reply to version based compilation

Interesting question! If I've understood correctly, you want to remove a subroutine alias, without actually undefining the subroutine itself. The only way I can think of to do that is:
# Usage: unalias ($package, $name) # Will remove the subroutine entry from the package's glob sub unalias { my ($package, $name) = @_; no strict; # Disable the safety systems local *temp; # Make a local glob my $glob = ${"${package}::"}{$name}; # Grab the glob *temp = *$glob{SCALAR}; # Copy the scalar part *temp = *$glob{ARRAY} if defined *$glob{ARRAY}; *temp = *$glob{HASH} if defined *$glob{HASH}; *temp = *$glob{IO} if defined *$glob{IO}; *temp = *$glob{FORMAT} if defined *$glob{FORMAT}; ${"${package}::"}{$name} = *temp; }
That seems to do what you asked for. So you can use File::Copy, and then at some point unalias('main', 'copy'); and the alias is removed. Is that what you meant?

Replies are listed 'Best First'.
Re: Re: version based compilation
by steves (Curate) on Dec 29, 2001 at 21:24 UTC

    Very cool. That works. Assign everything but the piece you don't want. That's one I didn't try. And it's so obvious once you see it.

    Since you solved that one, how about the bigger question that started me down this path: When a module's VERSION method is called, is there a way to stop compilation of the module at that point and switch to another one? This all started with an experimental piece of code like this:

    use Carp; sub UNIVERSAL::VERSION { my $class = shift; my $wanted_version = shift; my $fixed_version = $wanted_version; my $caller = caller(); my $version_class; $fixed_version =~ s/\./_/g; $version_class = "${class}_${fixed_version}"; eval <<"END_EVAL"; package $caller; no $class; require $version_class; $version_class->import(); END_EVAL croak "Version $wanted_version of $class not found ($version_class +): $@" if ($@); }

    I believe this works because the eval code runs after the BEGIN code (from use) that invoked the VERSION method. So the versioned copy of the module loads after, overwriting aliases. But ideally I'd want to just stop compilation of the non-versioned module so there are no BEGIN, CHECK, END type blocks pulled in.

    Thanks for the help on the one above. Most people I start talking typeglobs and symbol tables to just glaze over.

      Sadly, it's impossible to stop compilation of the module from a VERSION sub, because the module has already been compiled before the VERSION sub is invoked! You can check that by writing a BEGIN block which prints something -- you'll see that the BEGIN block is called before the VERSION sub.

      If you think about it, it has to be done that way. The module needs to be compiled first, otherwise the import() and VERSION() subs wouldn't be defined. Even though CHECK blocks are called later, it's still too late to stop them either: when a CHECK block is compiled, it's added to an internal list of routines to call at the end of compile time, and there's no way to modify that list without writing some hairy C code.

      If you have my Want module installed, you can stop the module use process dead from within the VERSION method: There's an undocumented internal routine Want::double_return which diddles perl's internal data structures so that when you return from the sub you're in, the sub that called you immediately returns as well. So if your VERSION routine contains:

      use Want (); Want::double_return(); return;
      then the use process will be stopped right there, and the import routine will never be called. Unfortunately that still won't stop BEGIN or CHECK blocks, and anyway it's rather too much like black magic for everyday use. Fun though :-)

        Very good info. Your Want package does about as much as I can do here it seems. I'll probably play around with that. I've learned quite a bit more about Perl today which is the Good Thing. Good point about compilation needing to be done for the subs to be defined, etc. I knew my thinking had holes in it. Thanks.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://135118]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (6)
As of 2024-03-28 12:12 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found