in reply to Re^6: Informal Poll: Traits (Long Post Warning!)
in thread Informal Poll: why aren't you using traits?

Can you (or anyone) think of any case where reblessing is useful, in the sense that solving the same problem another way would be awkward?

Makeshifts last the longest.

  • Comment on The need to rebless (was: Informal Poll: Traits)

Replies are listed 'Best First'.
Re: the need to rebless
by demerphq (Chancellor) on Nov 21, 2005 at 15:20 UTC

    I have objects that are lazily evaluated using rebless. Basically the objects represent a pricing scheme. Until $obj->price() is called the objects are just a hash of the parameters required to run a query out of the DB to get the data and are of the class 'Pricer::Stub', when Price::Stub::price() is called the routine extracts the required data and converts itself into a real Pricer object. And then calls price() a second time on the new object.

    Code using the Pricer object never knows or cares which object type is involved, as the Pricer objects are manufactored by a factory object.

    I used this because the $obj->price() method is called very often, and thus I didnt want conditional logic in the price() method itself to handle this behaviour. Personally I think this is a very effective design pattern and I'm happy to use it.

    ---
    $world=~s/war/peace/g

Re^8: Informal Poll: Traits (Long Post Warning!)
by Corion (Patriarch) on Nov 20, 2005 at 19:07 UTC

    When you have a generic proxy object like Object::Realize::Later, which more or less implements lazyness for method calls, it is quite convenient to have the object change class after it has been realized. Otherwise, lots of (brain-dead, I admit) checks fail when they ask UNIVERSAL::isa($obj,'foo');. Of course one could circumvent this problem with multiple inheritance or by writing a specialized ::Proxy class for every class to be lazy ...

      Override isa() in your code and tell anyone who calls it as a function that their code breaks yours, 'cuz it does.

      Class::LazyLoad doesn't need to do this. I wonder why you felt that Object::Realize::Later needed to do so.

      My criteria for good software:
      1. Does it work?
      2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?

        From a look at the documentation, Class::LazyLoad doesn't seem to support classes that implement cheap operations but can become the full fledged object on demand. Which is what Object::Realize::Later does. There are ways around this that don't need reblessing into the full class I guess, like aggregation/creation of a new instance, but reblessing is the easy/safe way. This is discussed in the Traps section of the documentation.

Re^8: Informal Poll: Traits (Long Post Warning!)
by adrianh (Chancellor) on Nov 21, 2005 at 17:33 UTC
    Can you (or anyone) think of any case where reblessing is useful, in the sense that solving the same problem another way would be awkward?

    I've seen it used with a class hierarchy that was based around incrementally parsing a serialised data structure. As the data was parsed it as reblessed to more and more specific classes as more was known about the structure in question. Quite neat.

    I've also occasionally used reblessing to implement state transitions.

Re: the need to rebless
by hv (Prior) on Nov 21, 2005 at 13:47 UTC

    I think the time I'm most likely to rebless an object is if I want to subclass an existing package to get some modified behaviour. Mostly in such cases I can simply inherit from the base class and Subclass->new will do the right thing, but in some cases the base class's new relies on the invoked class's name to create the right object.

    My work application has occasionally needed such tricks, since the underlying database abstraction uses the class name to find the object-to-database mapping information. However as of now, there is only one example of such reblessing in 50 KLOC (and that in a proof of concept utility that won't be updated), since most of the original needs for it were removed when the database abstraction was modified to call the invoked class's bless method. We do have 6 examples of classes that overload bless to do various interesting things, and most of those would originally have reblessed the objects instead.

    Hugo

      That strikes me mostly like a case of working around quirks in Perl’s OO, like bless with a single argument, rather than an innately useful application, though. Corion and demerphq on the other hand exploit reblessing for lazy realisation schemes, which seems innately valuable.

      Now I wonder if that inevitably requires reblessing; do people in languages that preclude changing the class of an object implement lazy realisation, and if so, how?

      Makeshifts last the longest.