Is unblessing perl objects a dreadful design?

南楼画角 提交于 2019-12-11 11:54:27

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!