Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

Re: Redefine package subroutines

by Melly (Hermit)
on Dec 19, 2012 at 14:05 UTC ( #1009565=note: print w/ replies, xml ) Need Help??


in reply to Redefine package subroutines

Okay, I think I'm there, but I'd like to check I'm not doing anything dangerous, and I have one mystery...

Here's the code (I've included the contents of the FP files at the end).

use strict; { package FP; sub foo{}; } package GP; { sub subtest1{return 'Global Test 1';} sub subtest2{return 'Global Test 2';} } package LP; { sub subtest1{return 'Local Test 1';} } { package AP; use base qw(FP LP GP); } #delete_FP(0); my $FP = 'test1.lib'; require $FP; print "test1.lib\n"; print GP::subtest1() . "\n"; # uses GP print FP::subtest1() . "\n"; # use FP subs defined in test1.lib print AP->subtest1() . "\n"; # as previous print AP->subtest2() . "\n"; # uses GP as this sub only defined there print AP->subtest3() . "\n"; # this sub won't exist in a moment... delete_FP($FP); $FP = 'test2.lib'; require $FP; print "\ntest2.lib\n"; print FP::subtest1() . "\n"; # uses FP subs defined in test2.lib print AP->subtest1() . "\n"; # as previous print AP->subtest3() . "\n"; # this sub now doesn't exist... sub delete_FP{ no strict 'refs'; my $class = 'FP'; my $symtab = $class . '::'; # Delete all symbols except other namespaces for my $symbol (keys %{$symtab}) { next if $symbol =~ /\A[^:]+::\z/; delete $symtab->{$symbol}; } delete $INC{$_[0]} if $_[0]; # in theory not nec. but tidier and all +ows us to require the same lib again? return 1; } __END__ #test1.lib file use strict; package FP; sub subtest1{ return 'FP Test 1'; } sub subtest3{ return 'FP Test 3'; } 1; #test2.lib file use strict; package FP; sub subtest1{ return 'FP Test 2'; } 1;

One mystery - there is a commented out call to delete_FP at line 24. If I don't comment this out, I get an error when I get to "print FP::subtest1()" on line 30, although the subsequent call to delete_FP seems to work fine - any ideas?

map{$a=1-$_/10;map{$d=$a;$e=$b=$_/20-2;map{($d,$e)=(2*$d*$e+$a,$e**2 -$d**2+$b);$c=$d**2+$e**2>4?$d=8:_}1..50;print$c}0..59;print$/}0..20
Tom Melly, pm (at) cursingmaggot (stop) co (stop) uk


Comment on Re: Redefine package subroutines
Select or Download Code
Replies are listed 'Best First'.
Re^2: Redefine package subroutines
by tobyink (Abbot) on Dec 19, 2012 at 14:33 UTC

    "One mystery - there is a commented out call to delete_FP at line 24. If I don't comment this out, I get an error when I get to "print FP::subtest1()" on line 30, although the subsequent call to delete_FP seems to work fine - any ideas?"

    Use FP->subtest1(), not FP::subtest1(). It's all about when the sub name is resolved to its implementation. Colons at compile-time; arrows at run-time. So FP::subtest1() gets bound at compile time to your original subtest1 function, but that gets destroyed when you delete the FP package. Even though you load a new subtest1 implementation, lines 30 and 40 are still bound to the original version of the function which has since disappeared.

    perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'

      Ah! - that's it. Many, many thanks...

      map{$a=1-$_/10;map{$d=$a;$e=$b=$_/20-2;map{($d,$e)=(2*$d*$e+$a,$e**2 -$d**2+$b);$c=$d**2+$e**2>4?$d=8:_}1..50;print$c}0..59;print$/}0..20
      Tom Melly, pm (at) cursingmaggot (stop) co (stop) uk

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others surveying the Monastery: (4)
As of 2015-07-28 01:44 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (251 votes), past polls