问题
Is unblessing Perl objects means having a dreadful design ?
If yes, can any one explain this to me ?
BTW, Here's the discussion which fired this question, check comments on the question
回答1:
Needing unbless
certainly raises eyebrows. Since you can still use the object as the original data structure, it's almost never needed.
Modules that are picky about receiving unblessed hash references vs objects tend to have options to not be so picky, for example allow_blessed and convert_blessed in JSON.
回答2:
One application is an object implemented as a hash reference and you also wish to
overload the %{}
dereferencing operator [EDIT: and you also want to support perls older than v5.10.1 -- otherwise you should just use no overloading.]
package Foo;
use overload '+' => sub { $_[0]->get + $_[1] },
...,
'%{}' => sub { return { foo => "bar", this => $_[0] } },
...;
Now for any $foo
that has type Foo
, trying to access an element like $foo->{$key}
will invoke your overloaded %{}
method, and your access will fail.
The workaround is to change your object's type temporarily while you access your object's member, and change it back when you are done. You could do this by unblessing your object, but it is more often done (and more easily done) by blessing it to a garbage value.
sub Foo::bar { # access 'bar' member of Foo object
my $self = shift;
# $self->{bar} will invoke Foo::{'%{}'}, and we don't wan't that
my $ref = ref $self;
unbless($self); # or bless $self, 'Not::An::Object::Name'
# now $self->{bar} is accessible
my $value = $self->{bar};
bless $self, $ref; # restore object type
return $value;
}
Another example is given in the section on "Two-face-References" in overload
I use this pattern here, for another example.
回答3:
This is an idle and silly question. You have no purpose in mind for unbless
but have chosen it at random from an obscure CPAN module to ask why it reflects bad design. You may as well ask how to undeclare a variable that has been declared with my
. That is also quite possible in XS code, but I hope it's clearly rather stupid?
The issue I have with unbless
is that you have created a data structure -- anything from a scalar variable or a file handle to a nested hash or array -- and called bless
so that Perl know how to resolve method calls on that object
So now you want to unbless
it. That will leave the data intact, and the main difference will be that any method calls will now result in a fatal error
Can't call method ... on unblessed reference
So what was your unbless
for? If you're relying on Perl to give you this fatal error then it's just as easy to assign undef
to the object which gives rise to this fatal error instead
Can't call method ... on an undefined value
but has the advantage that your data structure may be destroyed so that the memory is released
If you want something more solid then, because references may be passed to multiple sections of code, unbless
would be an example of action at a distance which is discredited by many more people than myself
来源:https://stackoverflow.com/questions/32029042/is-unblessing-perl-objects-a-dreadful-design