Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

Re^2: __PACKAGE__ in anonysub

by thpfft (Chaplain)
on Feb 19, 2005 at 20:07 UTC ( [id://432771]=note: print w/replies, xml ) Need Help??


in reply to Re: __PACKAGE__ in anonysub
in thread __PACKAGE__ in anonysub

It's not quite that simple: I know that bit works - that's why I'm using it - but I wasn't sure that it would work in a subclass. And you're quite right: I should have just tried it. So:

package Drone; sub new { return bless {}, shift; } 1; package Factory; no strict 'refs'; sub fixup { *Drone::bar = sub { return __PACKAGE__ }; } 1; package Subfactory; use base qw( Factory ); 1; package main; Subfactory->fixup; my $foo = Drone->new; print $foo->bar . "\n";

And it looks like the answer is no: this code prints 'Factory' for me, where I want it to say 'Subfactory'. Curses. So how can I get the name of the inheriting package inside the anonymous sub when fixup() is called? I guess I'll have to put in a package_name method and do it literally.

Thanks for putting my mind at rest about the other thing.

Replies are listed 'Best First'.
Re^3: __PACKAGE__ in anonysub
by Tanktalus (Canon) on Feb 19, 2005 at 20:27 UTC

    I know I'm not grasping all of your requirements here ... so maybe this will help you along your way.

    package Drone; sub new { return bless {}, shift; } 1; package Factory; no strict 'refs'; sub fixup { #*Drone::bar = sub { return __PACKAGE__ }; my $class = shift || __PACKAGE__; *Drone::bar = sub { return $class }; } 1; package Subfactory; use base qw( Factory ); 1; package main; Subfactory->fixup; my $foo = Drone->new; print $foo->bar . "\n";
    This prints out "Subfactory".

      Thank you! That won't work in my real situation, because I won't be calling a class method like that, but you made me realise that instead of __PACKAGE__, I just need to call ref $self, which will inherit properly. D'oh:

      my $self = shift; my $factory_class=ref $self; *Foo::bar = sub { return $factory_class->instance; };

      I definitely am creating a closure now, but I don't think it will matter: it's only a simple scalar that gets unnaturally prolonged.

      Thanks.

Re^3: __PACKAGE__ in anonysub
by ikegami (Patriarch) on Feb 19, 2005 at 20:36 UTC

    If it's a method, you could use:

    package Factory; sub fixup { no strict 'refs'; *Drone::bar = sub { my $self = shift; my $class = ref($self); return $class; }; } package main; Factory::fixup(); @Drone::Subclass::ISA = 'Drone'; my $drone1 = bless({}, 'Drone'); my $drone2 = bless({}, 'Drone::Subclass'); print($drone1->bar(), $/); # Prints Drone print($drone2->bar(), $/); # Prints Drone::Subclass

    or you could also use closures:

    package Factory; sub fixup { no strict 'refs'; my $pkg = 'Drone'; *{"${pkg}::bar"} = sub { return $pkg; }; } package main; Factory::fixup(); @Drone::Subclass::ISA = 'Drone'; my $drone1 = bless({}, 'Drone'); my $drone2 = bless({}, 'Drone::Subclass'); print($drone1->bar(), $/); # Prints Drone print($drone2->bar(), $/); # Prints Drone

    Note the slightly different output. I don't know which you would prefer.

      I'm sorry: I think I was very unclear in the original question, and simplified away the wrong bits. It's the package name of the factory that I want to capture in a method injected into the Drone class, so that the Drone (no idea why I called it that) can call instance() on the right factory class.

      The answer turns out to be very simple, and much the same as your neat constructions:

      sub post_require { my ($self, $class) = shift; my $factory_class=ref $self; no strict 'refs'; *{"$class::factory"} = sub { return $factory_class->instance; }; }

      but it does look like I can't do it without creating some kind of closure, which I was hoping to avoid...

      Thanks for your help.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://432771]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others lurking in the Monastery: (4)
As of 2024-04-18 05:19 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found