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;
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.
Re:Or with Sub::Install
hex on 2006-10-26T14:56:02
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; }
return $self;
}
Re:Nothing special
hex on 2006-10-27T09:38:56
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 to use __PACKAGE__. Handy.
On the other hand, the idiom of ( my $foo = $bar ) =~ s/x/y/; is a new and valuable one to me, which will definitely save me some time in future - thank you.
Re:Nothing special
Aristotle on 2006-10-27T12:46:37
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.
Re:that's not theft
hex on 2006-10-27T08:53:05
I guess it's theft in the same way that "downloading mp3s is theft!!1!":) Re:that's not theft
hex on 2006-10-27T09:16:01
Although, that said, no doubt actual theft is possible (and that there's already an Acme:: module to do it...).