Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

Problems and pitfalls with reblessing?

by Dallaylaen (Chaplain)
on Nov 22, 2018 at 07:46 UTC ( [id://1226164]=perlquestion: print w/replies, xml ) Need Help??

Dallaylaen has asked for the wisdom of the Perl Monks concerning the following question:

Hello esteemed monks,

Say I have an object that has a construction phase that ends via a finalize() method. After that, no more modifications may be made.

Currently it is implemented via a lock within the object. However, I'm tempted to do a bless $self, "My::Module::Readonly"; and remove mutators from that class (or make them dying stubs).

This looks simple and efficient, but blessing an object into another package smells like a hack and/or abuse of Perl object system. What are the possible problems/pitfalls with such approach?

One thing that comes to mind is extending the initial class. Are there more?

Replies are listed 'Best First'.
Re: Problems and pitfalls with reblessing?
by choroba (Cardinal) on Nov 22, 2018 at 08:58 UTC
    If both the source and target classes are yours, I don't see a big problem in reblessing between them. Just make sure you don't carry any unwanted internal state from the previous class.

    On the other hand, if you're using Mo*, there might be cleaner ways how to achieve the same, e.g. applying roles to an instance at runtime:

    'Moo::Role'->apply_roles_to_object($self, $read_only_class);

    It reblesses the object behind the scenes, anyway. To disable the writers, you probably need to around them.

    ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
      If you apply a role,doesnt that comes as an addition to the object's properties/methods ? Or do you mean that the role has properties with the same name as in the class so they overwrite them ?
        Changing the properties of the attributes works in the role:
        #!/usr/bin/perl use warnings; use strict; { package MyRole; use Moo::Role; has +x => (is => 'ro'); } { package MyObj; use Moo; has x => (is => 'rw'); sub finalize { 'Moo::Role'->apply_roles_to_object($_[0], 'MyRole'); } } my $o = 'MyObj'->new; $o->x(12); $o->finalize; $o->x(13); # x is a read-only accessor

        Another way is to wrap the accessor:

        { package MyRole; use Moo::Role; requires 'x'; before x => sub { die "x is read only" if @_ > 1 }; }

        ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
Re: Problems and pitfalls with reblessing?
by Anonymous Monk on Nov 22, 2018 at 07:56 UTC
    why buy a shotgun when asking nicely is enough?
      In most cases, yes. But, as a module user, I'd prefer it dying on erroneous operation rather than "asking politely".

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others admiring the Monastery: (5)
As of 2024-04-24 01:57 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found