http://www.perlmonks.org?node_id=183348


in reply to How can I unbless an object?

But isn't this already as simple as you could get? Here's the code I've played with:
use Data::Dumper; my $bhash = bless { key1 => 'val1', key2 => 'val2' }, 'FOO'; my %uhash = %$bhash; print Dumper($bhash); print Dumper(\%uhash); print "done\n";
And the output is:
$VAR1 = bless( { 'key1' => 'val1', 'key2' => 'val2' }, 'FOO' ); $VAR1 = { 'key1' => 'val1', 'key2' => 'val2' }; done
The bless() is used to associate the object a reference points to with a package that defines the object class. I am frankly not aware of any operator in Perl for 'curse' or 'unbless'.

Update: mp when you use the bless() operator on a hashref like so:
my %ahash = ( key1 => 1, key2 => 2 ); bless \%ahash, 'FOO';
You end up 'labeling' or 'associating' the %ahash structure with the package 'FOO'. Here's the code to prove this:
use Devel::Peek 'Dump'; use Data::Dumper; my %ahash = ( key1 => 'val1', key2 => 'val2' ); print "ORIGINAL HASH:\n"; print Dumper(\%ahash) ."\n"; print Dump(\%ahash) ."\n\n"; my $bhash = bless \%ahash, 'FOO'; print "ORIGINAL HASH (after blessing, note it's now been associated wi +th the 'FOO' package!!):\n"; print Dumper(\%ahash) ."\n"; print Dump(\%ahash) ."\n\n";
Which when you run it produces this output:
ORIGINAL HASH: $VAR1 = { 'key1' => 'val1', 'key2' => 'val2' }; SV = RV(0x3b828) at 0x2307c REFCNT = 1 FLAGS = (TEMP,ROK) RV = 0x2dbc4 SV = PVHV(0x8ea80) at 0x2dbc4 REFCNT = 2 FLAGS = (PADBUSY,PADMY,SHAREKEYS) IV = 2 NV = 0 ARRAY = 0x25160 (0:6, 1:2) hash quality = 150.0% KEYS = 2 FILL = 2 MAX = 7 RITER = -1 EITER = 0x0 Elt "key1" HASH = 0x3e4d49 SV = PV(0x23444) at 0x2316c REFCNT = 1 FLAGS = (POK,pPOK) PV = 0x952b8 "val1"\0 CUR = 4 LEN = 5 Elt "key2" HASH = 0x3e4d4a SV = PV(0x2342c) at 0x23250 REFCNT = 1 FLAGS = (POK,pPOK) PV = 0x952e8 "val2"\0 CUR = 4 LEN = 5 ORIGINAL HASH (after blessing, note it's now been associated with the +'FOO' package!!): $VAR1 = bless( { 'key1' => 'val1', 'key2' => 'val2' }, 'FOO' ); SV = RV(0x3b828) at 0x2307c REFCNT = 1 FLAGS = (TEMP,ROK) RV = 0x2dbc4 SV = PVHV(0x8ea80) at 0x2dbc4 REFCNT = 3 FLAGS = (PADBUSY,PADMY,OBJECT,SHAREKEYS) IV = 2 NV = 0 STASH = 0x59b1c "FOO" ARRAY = 0x25160 (0:6, 1:2) hash quality = 150.0% KEYS = 2 FILL = 2 MAX = 7 RITER = -1 EITER = 0x0 Elt "key1" HASH = 0x3e4d49 SV = PV(0x23444) at 0x2316c REFCNT = 1 FLAGS = (POK,pPOK) PV = 0x952b8 "val1"\0 CUR = 4 LEN = 5 Elt "key2" HASH = 0x3e4d4a SV = PV(0x2342c) at 0x23250 REFCNT = 1 FLAGS = (POK,pPOK) PV = 0x952e8 "val2"\0 CUR = 4 LEN = 5
Note that soon after the call to the 'bless' operator, the original hash structure was altered. There's now been a new 'STASH' field added to the hash RV structure. Again, as far as I know there's no means in current version of Perl to simply yank that field from the underlying hash structure. I'll play some more with this to see if there's a way of obtaining an unblessed structure without unnecessary copying however.

_____________________
# Under Construction

Replies are listed 'Best First'.
Re: Re: How can I unbless an object?
by mp (Deacon) on Jul 19, 2002 at 18:28 UTC
    What you suggest works and is basically what I'm currently doing, but I would prefer not to have to waste resources to copy the hash just to get a non-blessed copy of it, especially when the particular application of this can end up making a copy of some fairly large hash of array of hash of ... - type structures.

    Update: changed wording slightly.

      Please see my updated post above.

      Also, looking at your particular application of this, I can't quite understand why do you need to worry much about blessed entities (structures). No matter what 'class' name your hash structure has been branded with, in the end you still deal with the same hash structure. The $self variable is simply referencing that 'named' structure. And when you do $self->method(), Perl simply interprets it as FOO::method($self) on the basis that '$self' has been 'labeled' as belonging to the package or being of type 'FOO'. That's all. Nontheless, I can still do this:
      package FOO; sub new { bless { key1 => 1, key2 => 2 }; } package main; my $foo = new FOO(); print "Look, first key = '$foo->{key1}'!\n";
      Output:
      Look, first key = '1'!
      Clearly, that $foo object is nothing but a reference to a hash. Simple as that.

      _____________________
      # Under Construction
        That works for normal perl, but not for templates in Template Toolkit (TT2), which is what the attempted unblessed object is for use with. TT2 uses a "dot" (.) notation rather than normal perl syntax, then tries to figure out what to do based on the type (I think it just looks at ref($whatever), but I am not very familiar its inner workings) when it compiles the template.

        When you say something like [% d.e.f %], TT2 will actually use $d->e->f or $d->e->{f} or $d->{e}->{f}, etc., depending on what $d and $d->e (or $d->{e}, etc.) really is. This is the DWIM behavior that Randall referred to above.