Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW
 
PerlMonks  

Re: Converting Moose object to a subclass of itself

by nysus (Parson)
on Feb 26, 2017 at 21:00 UTC ( [id://1182896]=note: print w/replies, xml ) Need Help??


in reply to Converting Moose object to a subclass of itself

I think I found what I needed: $metaclass->rebless_instance

$PM = "Perl Monk's";
$MCF = "Most Clueless Friar Abbot Bishop Pontiff Deacon Curate";
$nysus = $PM . ' ' . $MCF;
Click here if you love Perl Monks

  • Comment on Re: Converting Moose object to a subclass of itself

Replies are listed 'Best First'.
Re^2: Converting Moose object to a subclass of itself
by stevieb (Canon) on Feb 26, 2017 at 21:14 UTC

    Can you explain why you're wanting to do this? Why not just use the instance of the child object directly, and leave the parent as-is, as a parent class object? Or if you want to use the child object through the parent, stuff a copy of the object into the parent and use it from there?

    It seems as though re-blessing the object may lead to potential confusion down the road, and may break things if someone tries to generate another object from the parent, instead of using the class:

    # this may break/do something unexpected if $self is # re-blessed my $obj = $self->new(%params); # worse, the wordpress child probably doesn't have a wordpress_new() # method, as it has no need to. The parent probably calls new() on the # child through a wordpress-type instantiator my $obj = $self->wordpress_new();

    Confusion?

    my $parent = Foo::Bar->new; # after rebless, calling a documented method in the parent # class may cause major confusion (or worse, subtle breakage far away) # if the child has the same method overridden, and does something # totally different $parent->documented_method(); # got foo and not bar!?

      I'll do my best to explain. Basically, my thought is that the methods for each subclass will be different. For example, the method to obtain the database password for a Drupal site is different than the method for obtaining a WordPress database password. Each CMS has a differently named config file and a different way of storing the password in the config file. So, it seems to me, that it would be good to set up two subclasses, one for Drupal and one for WordPress, that have methods specialized for obtaining the database password and other settings.

      $PM = "Perl Monk's";
      $MCF = "Most Clueless Friar Abbot Bishop Pontiff Deacon Curate";
      $nysus = $PM . ' ' . $MCF;
      Click here if you love Perl Monks

        I believe I understand. What I'd do, is have your Parent have methods that returns the appropriate thing:

        # parent sub new { return bless {}, shift; } sub wordpress { my ($self, %params) = @_; return My::Dist::Wordpress->new(..., %params); } # user code my $parent = My::Dist->new; my $wordpress_obj = $parent->wordpress(%params);

        Does that make sense? Again, you can hold the child objects within the parent object if you need to maintain running information about them. Let me know if you'd like a brief example of that scenario.

        Note that some parent class code sets up a lot of stuff before returning a child object. Other times not. If not, you could simply do:

        my $wp_obj = My::Dist::Wordpress->new(...);

        That bypasses parent->child inheritance, so fetching from the parent obj may be better, again, because you may want to keep track of child info, or you may want all of your DB/config/setup stuff within the parent, then have the parent create the child with a special instantiation call, while passing in this special data. Doing it through the parent object (former example) would have parent do *all* of the config reading, then just pass along relevant details to the relevant child init (this is my preferred way in most situations, so configs etc get read only once).

        When I create multi-level inheritance classes, iirc, I 'hide' all of the child classes, so that a user doesn't need to know about them whatsoever. See here for a pretty simple example where I let the parent pull in objects of different types, and dish them out. In that case, there's no state tracking.

        Here's a reasonably more complex example, where I have two classes, parent and child, where I stuff the child inside the parent so the parent can use the child directly, and the child can actually use the parent as well. This requires some REFCNT (reference counting) manipulation, so that we don't leak.

      "Can you explain why you're wanting to do this?"

      OP is clueless.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others chilling in the Monastery: (3)
As of 2024-04-26 00:40 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found