in reply to Possible to change package of code reference?

I'd be willing to bet this is an XY Problem... could you explain why you need this, preferably with an SSCCE?

If you want the code that $func points to to call a different run, you can do the following (locally redefine &Spin::Command::spin::run), although this is kinda hacky too <update> because it just changes the call to run, it doesn't affect anything else in $func, like package variables or other function calls. </update> The "real" solution would be to modify $func at its origin.

use warnings; use strict; { package Spin::Command::spin; sub run { print "Bar<<".shift.">>\n"; } sub func { run("Foo:".shift); } } my $func = \&Spin::Command::spin::func; use B::Deparse; my $deparse = B::Deparse->new; print "<<",$deparse->coderef2text($func),">>\n"; sub other_run { print "Quz[[".shift."]]\n"; } my $func_other_run = sub { no warnings 'redefine'; local *Spin::Command::spin::run = \&main::other_run; $func->(@_); }; $func->("Hello"); # prints "Bar<<Foo:Hello>>" $func_other_run->("World"); # prints "Quz[[Foo:World]]"

Update 2: Of course you can also just clobber the original func:

{ no warnings 'redefine'; *Spin::Command::spin::func = $func_other_run; }

WebPerl Live Demo

Replies are listed 'Best First'.
Re^2: Possible to change package of code reference?
by nysus (Parson) on Oct 21, 2018 at 21:08 UTC

    An SSCCE would entail explaining a kind of dumb thing I'm doing in the first place. Perhaps I'll save that for another post. I was able to accomplish what I needed to by noodling out Lanx's suggestion. Cool job on the Live Demo, btw.

    $PM = "Perl Monk's";
    $MCF = "Most Clueless Friar Abbot Bishop Pontiff Deacon Curate Priest Vicar";
    $nysus = $PM . ' ' . $MCF;
    Click here if you love Perl Monks

      I was able to accomplish what I needed to by noodling out Lanx's suggestion.

      Ok, but note LanX's warning, which I agree with - B::Deparse is more of a debugging tool, and does not guarantee to be able to round-trip Perl code, so your solution will be quite brittle. Using a regex to replace the package name will blow up on something as simple as:

      package Spin::Command::spin; our $foo = "Bar"; sub func { print "Foo:$foo"; }

      Because the deparse of func is:

      { package Spin::Command::spin; print "Foo:$foo"; }

      If, as you seem to be saying here, you really just want to replace run and don't need other replacements, then my suggestion, even though it's still kind of a hack, is much more robust (relative to it being a hack, at least).