Stories
Slash Boxes
Comments
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

Ovid (2709)

Ovid
  (email not shown publicly)
http://publius-ovidius.livejournal.com/
AOL IM: ovidperl (Add Buddy, Send Message)

Stuff with the Perl Foundation. A couple of patches in the Perl core. A few CPAN modules. That about sums it up.

Journal of Ovid (2709)

Monday October 18, 2004
12:08 PM

A Class within a Subroutine

[ #21392 ]

Sometimes refactoring will take you down some strange paths. I have a subroutine that needs to be exported to other test classes. This subroutine mocks up certain portions of the SOAP::Lite interface so I can pass in the return XML and also see what the request XML looks like. I've implemented an entire class within a subroutine. I don't think this is really a good piece of code, but it was interesting to write.

sub _mock_soap_interface {
    package MOCK::SOAP::INTERFACE;
    require Sub::Override;
    require SOAP::Lite;

    my $request = '';

    my $xml  = shift;
    my $token = Sub::Override->new(
        'SOAP::Lite::call',
        sub {
            my $self = shift;
            my $serializer = $self->serializer;
            $request = $serializer->envelope(method => shift(@_), @_);
            return $xml;
        }
    );
    *MOCK::SOAP::INTERFACE::xml = sub { ${shift->{_request}} };
    bless {
        _request => \$request,
        _token   => $token,
    } => __PACKAGE__;
}

And using it:

my $request = _mock_soap_interface($response_xml);
my $soap = My::SOAP::Lite::Subclass->new;
my $results = $soap->get_some_service;
# test results
my $request_xml = $request->xml;
# test that request XML is properly formatted

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
 Full
 Abbreviated
 Hidden
More | Login | Reply
Loading... please wait.
  • I'm confused.

    What does it mean to change package within a sub?
    • Well, package declarations are lexically scoped. It would have been simpler for me to have simply declared another package in that file and have the subroutine return a new object created from that package. Instead, just because of the way the refactoring worked, I had simply wrapped the package in the sub and now that I look at it, I can't see why this would be a bad thing.

      There's no real benefit that I can tell, but there's no real harm I can identify, either.

    • Quite simply, it means that when you enter the sub you're in one package, and then at some point during the sub the current package changes. I recently did something like that, and it was also because of some refactoring.

      I have a bunch of classes, all subclasses of a single class, and all pretty similar. I broke a ton of code out into a "helper" module which they all use. However, part of that is to call a method in the class's superclass, like this:

      package Foo;
      @ISA(qw(Bar));

      use HelperMethods;