Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
PerlMonks  

Doubt about fly-weight objects.

by blazar (Canon)
on May 17, 2005 at 09:06 UTC ( [id://457709]=perlquestion: print w/replies, xml ) Need Help??

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

As some of you may have understood by some posts of mine I'm pursuing some interest in object orientation in Perl...

Now, I've read a few documents about fly-weight and inside-out objects, and while I understand perfectly

  1. which is the problem that the latter ones try to cope with, and why they succeed in doing so,
  2. that the latter ones are a generalization (or a special case?) of the former ones,
I don't see which is the actual advantage of fly-weight objects over "standard" ones, apart some moderate amount of conceptual cleanliness. Or is there something obvious that I'm missing?

Question #2

Also, I'm very curious as to know wether someone has ever met any situation in which it has been useful or sensible to have part of the data "inside" the object and part of it stored in a package lexical: possibly by still using the object's blessed reference as in index into a hash, or by some other technique...

Perhaps, thinking of a reblessed object, as suggested to me in Re: Instance data inheritance?, such a technique may be used to include additional attributes to the child object without having to fiddle with the parent one's internals...

Replies are listed 'Best First'.
Re: Doubt about fly-weight objects.
by polettix (Vicar) on May 17, 2005 at 09:27 UTC
    Flyweight Pattern in The Portland Pattern Repository could be a good starting point. In particular, I see that this link inside the page also points to interesting "stories" of usage of the pattern, which could help you get it better.

    Flavio (perl -e 'print(scalar(reverse("\nti.xittelop\@oivalf")))')

    Don't fool yourself.
      Indeed I found these links interesting especially in that they show that the concept is not perl-specific as I would have naively thought.

      It seems to me that the basic aspect on which most references that were given to me concentrate is that of caching, which supports the actual "light" nature of these objects, as of the name attribution.

      However it doesn't seem to me that the typical example one sees about them is really any lighter than "standard" objects. Granted, I see how one could make them so, but that's a different story. Perhaps flyweight objects are really flyweight in other OO {models,languages}.

      Note: With the above I mean that the typical perl example of a constructor is:

      sub new { my $class = shift; my $id = bless [] => $class; $data{$id} = { foo => undef, bar => undef }; # ... $id; }
      or (to speak about Inside-Out):
      sub new { my $class = shift; my $id = bless [] => $class; $foo{$id} = undef; $bar{$id} = undef; # ... $id; }
      Sometimes one sees \(my $bogus) instead of [], but basically in these typical constructors a unique id is associated to each object, different for all of them.

      Side note - OT

      While I think that WiKi's such as the referenced one are generally precious resources, I also find their extremely hypertextual nature occasionally confusing and annoying: I tend to have the impression that there may be some relevant node that I missed. Sometimes a slightly more sequential organization would come useful.

      Now one -well, I for one- wonders how an ordering could be find (maybe automatically or semiautomatically) in a document that is inherently hypertextual as to make it into a sequential thing...

        The conceptual problem you're running into is that Perl's OO model isn't "normal". Every object is a reference, no matter how you slice'n'dice it. This is unlike other languages.

        I've never really had a use for flyweights - either I need a real object or I don't. But, that's just me.


        • In general, if you think something isn't in Perl, try it out, because it usually is. :-)
        • "What is the sound of Perl? Is it not the sound of a wall that people have stopped banging their heads against?"
      Flyweight Pattern in The Portland Pattern Repository could be a good starting point. In particular, I see that this link inside the page also points to interesting "stories" of usage of the pattern, which could help you get it better.

      One thing to watch out for when people use the term "flyweight" in the Perl community is that they are sometimes using it as TheDamian used it in his excellent Perl OO book, which was in a slightly different way from the GoF defined it. See Flyweights - different meaning in perl? for gory details.

Re: Doubt about fly-weight objects.
by sh1tn (Priest) on May 17, 2005 at 09:39 UTC
      An extremely good link indeed!

      Actually the code examples given there support (IMHO) what I wrote in Re^2: Doubt about fly-weight objects., i.e. that the aspect that is mostly stressed is that of caching. But then again, it wasn't much touched upon in all of the previous examples of flyweight objects I had seen.

      This actually raises in me a related question: if it's only for caching, can't one still obtain it with a lexical hash with "standard" objects? I mean, something a' la:

      { my %seen; sub new { my $class = shift; my ($this, $value)=@_; my $id = unique_id $this, $value; $seen{$id} ||= bless { THIS => $this, VALUE => $value }, $class; } # Suitable DERSTROY here... }
      In other words, the two concepts, i.e. that of caching and that of storing the actual object's data in package lexical "outside" of the object itself are mostly orthogonal. Aren't they?
Re: Doubt about fly-weight objects.
by Fletch (Bishop) on May 17, 2005 at 10:49 UTC

    IIRC the point of flyweights is when you have a boatload of instances of a class and having each instance carry around the entire state would take a huge amount of memory. The example given in the Gang Of Four book is an OO text editing widget in which each individual character is represented by a character object.

      IIRC the point of flyweights is when you have a boatload of instances of a class and having each instance carry around the entire state would take a huge amount of memory.

      No, all of the data still exists, it is just all stored in one big heap in the class, rather than piecemeal with each obect instance. Saying that this saves memory usage is kind of like saying that dropping something heavy from your hands will reduce the total mass of the universe. Flyweight objects are so named because they, themselves, consume next-to-no memory, but the total memory used is not reduced; it's just used in a different place (within the same process).

      ------------ :Wq Not an editor command: Wq

        Erm, (using the GoF example of flyweights for characters) if you compare several thousand individual instances of class Letter { char myLetter; } scattered all over the heap versus having several thousand Letter * pointers to the same set of 128/256/n instances living inside the flyweight class it most certainly will use less memory.

Re: Doubt about fly-weight objects.
by herveus (Prior) on May 17, 2005 at 12:06 UTC
    Howdy!

    My sense is that there are two distinct matters people are trying to address when the think of "Flyweight Objects". In some languages, objects are bulky struct-like things, instead of references. Passing these chunky objects around is relatively expensive. If objects are always simply a reference to something, then this concern simply never comes up.

    The more useful (in my opinion) facet (and really the one covered under "Flyweight Pattern") is where you expect to need a large number of instances of the class, but where many will likely be effectively identical. For example, rows of data from a table.

    In this case, if the Class manages a pool of instances so that instances that appear to be the same are in fact the same (which means that context-dependent state must be maintained external to the object), then you ask the class to give you an object for the key "x". The class keeps track of the instances it has created and gives you the one it made a while back for that key (or creates one if necessary).

    I meditated on this a couple years ago at On Flyweights... (with sneaky segue to data modeling), and I think my thoughts still stand.

    yours,
    Michael
      I meditated on this a couple years ago at On Flyweights... (with sneaky segue to data modeling), and I think my thoughts still stand.
      Ok, I'm not terribly familiar with relational databases, but I take your point. Somehow it may help me also in the reverse direction...
Re: Doubt about fly-weight objects.
by Ctrl-z (Friar) on May 17, 2005 at 12:24 UTC

    Also, I'm very curious as to know wether someone has ever met any situation in which it has been useful or sensible to have part of the data "inside" the object and part of it stored in a package lexical: possibly by still using the object's blessed reference as in index into a hash, or by some other technique...

    I do this sometimes. Usually when I want private data and the object to behave in public like its underlying blessed type (eg, keys %$obj). This can be more useful than having special key prefixes or other nonsense - but by Software Engineering standards its pretty poor form. Good for quick n' dirty stuff though ;-)




    time was, I could move my arms like a bird and...
      I do this sometimes. Usually when I want private data and the object to behave in public like its underlying blessed type (eg, keys %$obj). This can be more useful than having special key prefixes or other nonsense - but by Software Engineering standards its pretty poor form. Good for quick n' dirty stuff though ;-)
      Interesting. It doesn't seem to me so atrocious after all. Fortunately perl is flexible enough that you can decide what is good and what is evil depending on the problem at hand in each particular situation.

      The problem is that experienced hackers do know when they're doing something that is potentially Bad(TM), and they do on purpose - because they know what they're doing, while occasionally you can see newbies using the same techniques in a totally uninformed matter, which contributes to the spreading of bad programming techniques - what that sometimes in turn contributes to give Perl a bad name...

Re: Doubt about fly-weight objects.
by mpeters (Chaplain) on May 17, 2005 at 13:49 UTC
    Also, I'm very curious as to know wether someone has ever met any situation in which it has been useful or sensible to have part of the data "inside" the object and part of it stored in a package lexical: possibly by still using the object's blessed reference as in index into a hash, or by some other technique...

    Class::DBI does exactly this. If enabled, there is an 'object index' which makes sure that there is only one instance of a given table row existing as an object at a time. This doesn't provided caching, but a means to make sure that you don't do something stupid since they aren't really multiple objects, just refs to the same row.

    -- fast, working, cheap - pick two
      Class::DBI does exactly this. If enabled, there is an 'object index' which makes sure that there is only one instance of a given table row existing as an object at a time. This doesn't provided caching, but a means to make sure that you don't do something stupid since they aren't really multiple objects, just refs to the same row.
      Interesting, especially since I do use Class::DBI, but mostly in a relatively naive way, since I've been exposed to it by more experienced (in Class::DBI itself, that is - and in DBses in general) coworkers.
Re: Doubt about fly-weight objects.
by diotalevi (Canon) on May 17, 2005 at 19:12 UTC

    I've only seen one useful use of this in perl and it was absolutely necessary in that case: when you've overloaded the type of dereferencing the object is based on. Data::Postponed uses scalar based objects and overloads everything including ${}. This now effectively prevents me from storing anything inside the object because I can never get access to it. The workaround is to use the object's stringification "Data::Postponed::Forever=SCALAR(0x8141758)" as a key to a global and store all of the object's internals in that global.

Re: Doubt about fly-weight objects.
by Anonymous Monk on May 17, 2005 at 16:18 UTC
    You can avoid adding your own caching by using Memoize: use Memoize; memoize('new'); This wraps your constructor with a caching version. It may not be faster, but the resulting code is cleaner.
      I do know about memoize. It must have been one of the very first modules I ever discovered - I seem to remember having read about it in an article. Generally I prefer to do memoizing by myself: don't know why and couldn't give any good reason - generally I'm not terribly concerned about efficiency, especially micro-optimization-wise.

      I must admit, however, that for some other reason I couldn't say, I had never thought of using it on (subs called like) methods.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others chilling in the Monastery: (4)
As of 2024-03-28 21:31 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found