in reply to Overriding a module that is used by a program I'm testing

You could also stomp around in Proc::Background's namespace. Generally a bad idea, but it can be useful in cases like this.
use Proc::Background; # Make sure it's loaded at compile-time package Proc::Background; no warnings 'redefine'; sub new { do_stubby_stuff(@_) } package main; # Go about your testing business
This will replace Proc::Background::new with your own version, which can do whatever works best for your tests. Note, though, that this doesn't allow for using SUPER to access the original version of the replaced sub(s) because it's redefining the existing sub, not overriding them in proper OO fashion.

Replies are listed 'Best First'.
Re^2: Overriding a module that is used by a program I'm testing
by Narveson (Chaplain) on Dec 08, 2010 at 15:17 UTC

    Wow! The called program is going to load the module, so pre-empt it by loading it myself! I liked this and used it. Thanks!

    As for your warning about how this isn't a proper OO override: noted, but in this particular setting I am aiming for total suppression. In fact I went and condensed your suggestion to the following:

    # pre-empt the loading use Proc::Background; { no warnings 'redefine'; *Proc::Background::new = sub {}; }

    having realized that my stub of choice was a no-op.

      I don't get how that works. use() isn't require(), that is, won't the test code reload Proc::Background and install its version of Proc::Background::new in the symbol table, overwriting the sub reference you installed in the symbol table for Proc::Background::new?

      edit: Never mind. The following are equivalent:

      use Proc::Background #and BEGIN { require Proc::Background; Proc::Background->import; }

      So the second use/require won't do anything.

      Also, couldn't you simply perform a substituion (s///) on launch_rockets.pl and delete the offending lines?

Re^2: Overriding a module that is used by a program I'm testing
by anonymized user 468275 (Curate) on Dec 08, 2010 at 22:38 UTC
    I like this solution. I needed to do something similar today as it happens. I wanted to replace only certain methods, so I put a copy of the CPAN module in a Replacement subdirectory, complete with its parent directory, amended it and:
    use library '/home/simon/lib/Replacement'; use Replacement::Some::Module; ...

    One world, one people

      I needed to do something similar myself about a month ago, too... The result was LocalOverride, which hooks into the require mechanism (by putting a coderef into @INC, as cdarke suggested above) to accomplish what you've described transparently. With the default configuration, LocalOverride would cause
      use Some::Module;
      to more-or-less turn into
      use Some::Module; use Local::Some::Module;
      ("More-or-less" because Some::Module::import runs only after both versions are loaded, not once after the base module loads and again after the local modifications load.)

      Also note that, with this technique, you don't need to use a complete copy of the base module as a baseline. So long as you load both Some::Module and then Replacement::Some::Module, you only need to include changed subs in Replacement::Some::Module.