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 ]

hex (3272)

hex
  (email not shown publicly)
http://downlode.org/

Perl, RDF and wiki hacker, London, UK. This is my former Perl blog; I now write at Earle's Notebook [downlode.org].

Journal of hex (3272)

Thursday October 26, 2006
09:05 AM

Method theft

[ #31425 ]
So, I just wrote the following: steal a method wholesale from somewhere else. (Not incredibly sophisticated, but new for me.) I don't currently have a particular use for it, but it seems to have potential for fun.

#!/usr/bin/perl

use warnings;
use strict;

package Foo;

sub foo {
    print "1\n";
}

package Bar;

sub new {
    bless {}, shift;
}

sub steal {
    my ($self, $call) = @_;

    my @segments = split('::', $call);
    my $method = pop @segments;
    my $class = join '::', @segments;

    no strict 'refs';
    *{__PACKAGE__ . "::$method"} = *{$class . "::$method"};

    $self;
}

package main;

Bar->new->steal("Foo::foo")->foo;

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 think you may do the same with Sub::Install (by rjbs). The code would be something like:

      use Sub::Install;
      Sub::Install::install_sub({
        code => 'foo',
        from => 'Foo',
        into => 'Bar',
      });

    Note: Your code currently does not handle packages like 'Data::Foo::Glub' as the source.

    • I think you may do the same with Sub::Install (by rjbs).

      Smooth! Thanks for the tip.

      Note: Your code currently does not handle packages like 'Data::Foo::Glub' as the source.

      Good call. I've fixed it now so that it does.

  • That’s just how exporting works in Perl.

    You’re better off doing it like so, btw:

    *{__PACKAGE__ . "::$method"} = \&{$class . "::$method"};

    That affects only the subroutine slot of the destination glob, and avoids nuking it in entirety.

    You’re doing a lot of pointless busywork, though:

    sub steal {
        my $self = shift;
        my ( $symref ) = @_;

        ( my $methname = $symref ) =~ s/^.*:://;

        { no strict 'refs'; *$methname = \&$symref; }

    • That’s just how exporting works in Perl.

      Cool. All part of the learning process.

      You’re better off doing it like so, btw... That affects only the subroutine slot of the destination glob, and avoids nuking it in entirety.

      Yeah. I realised that a little later after some more reading on globs.

      You’re doing a lot of pointless busywork, though:

      I call it a first pass! The split/pop/join would most likely have become a regex the next time I looked at it. I see that it also obviates the need

      • Oh yeah. That’s a specific instance of a broader idiom that comes in many forms. An instance you have probably encountered elsewhere is chomp( my @line = <$fh> );. It looks somewhat different, but it operates on the same principle: using parens to increase the precedence of an assignment so it happens before another part of the expression, which then operates on the lvalue of the assignment.

        Use it sparingly, though, as overuse of this idiom can easily degrade readability.

  • If you *steal* you should delete the method from the original owner, no?
    • I guess it's theft in the same way that "downloading mp3s is theft!!1!" :)
      • Although, that said, no doubt actual theft is possible (and that there's already an Acme:: module to do it...).
  • This reminds me of Acme::Magpie [cpan.org]