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

Lets say I have two modules called Pileofrogs::Frob and Pileofrogs::Util. I realize that the subrutine Pileofrogs::Frob::frob would really be better as Pileofrogs::Util::frob.

My inclination is to ..

  1. Add frob to Pileofrogs::Util
  2. Edit what scripts I can to use Pileofrogs::Util rather than Pileofrogs::Frob.
  3. Make Pileofrogs::Frob load frob from Pileofrogs::Util so any scripts that depend on frob don't break if I forgot to update them to use Pileofrogs::Util.

So, two questions:

  1. Am I crazy?
  2. How would I go about making Pileofrogs::Frob transparently hand me Pileofrogs::Util::frob when I ask for Pileofrogs::Frob::frob?

Thanks! I hope my question makes more sense than I fear it does....

--Pileofrogs

Update: Ooh, if I were really cool, I could even make Pileofrogs::Frob recommend using Pileofrogs::Util in some nice way when someone calls Pileofrogs::Frob::frob...

Replies are listed 'Best First'.
Re: Renaming a module
by ikegami (Patriarch) on Feb 17, 2006 at 00:41 UTC
    Am I crazy?

    With modules named like that, surely! ;)

    How would I go about making Pileofrogs::Frob transparently hand me Pileofrogs::Util::frob when I ask for Pileofrogs::Frob::frob?
    package Pileofrogs::Frob; sub frob { warn("Redirecting Pileofrogs::Frob::frob to Pileofrogs::Util::frob\ +n") unless our $frob_warning++; require Pileofrogs::Util; &Pileofrogs::Util::frob }
    Update: More efficient:
    package Pileofrogs::Frob; sub frob { warn("Redirecting Pileofrogs::Frob::frob to Pileofrogs::Util::frob\ +n"); require Pileofrogs::Util; { no warnings 'redefine'; *frob = \&Pileofrogs::Util::frob; } &frob }

    Update: Switched from goto &frob; to &frob;. The latter is faster.

Re: Renaming a module
by friedo (Prior) on Feb 17, 2006 at 00:47 UTC
    1. You might be, depending on your reasons for doing it.
    2. There are a couple ways.

    One possibility is to alias the symbol from one package to another.

    package Pileofrogs::Util; *{"Pileofrogs::Frob::frob"} = \*{"Pileofrogs::Util::frob"}; sub frob { print "frob!"; } package main; Pileofrogs::Frob->frob; Pileofrogs::Util->frob;

    Another way is to just change the original sub to one that calls the new one. You can also use this to emit a warning.

    package Pileofrogs::Frob; use Carp 'carp'; sub frob { carp "You should really use Pileofrogs::Util::frob"; Pileofrogs::Util->frob( @_ ); }
Re: Renaming a module
by kwaping (Priest) on Feb 17, 2006 at 18:16 UTC
    How about this?
    1. Add frob to Util.
    2. Remove frob from Frob.
    3. add use base Pileofrogs::Util; to Frob.
    What do you guys think, would that work too?
      It will work if and only if frob() is a method call. In other words, if you call Pileoffrogs::Frob::frob(), it will not work using the method you describe. But if you call Pileoffrogs::Frob->frob(), it will. If you want Pileoffrogs::Frob::frob() to work, you'll need to add this to Pileoffrogs::Frob::Util:
      use Exporter; our @EXPORT_OK = qw(frob);
      and change the use base line in Pileoffrogs::Frob:
      use base Pileoffrogs::Util (frob);
      Hope that helps..