Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

Composition Examples Sought

by darrel3edndcom (Novice)
on May 24, 2002 at 00:34 UTC ( #168941=perlquestion: print w/ replies, xml ) Need Help??
darrel3edndcom has asked for the wisdom of the Perl Monks concerning the following question:

In section 8.3.4 of Advanced Perl Programming, "Composition" is recommended as a Good Thing (tm), but with no examples of how one might go about implementing a object made of components....
I'm not terribly interested in using the ObjectTemplate.pm -- or maybe I _am_ terribly interested, and that's the problem. In any case, can any monk show me how to re-code this object using composition methods?
package Monk; sub new { my ($name, $password, $realname) = @_; my %monk = ( "name" => $name, "password" => $password, "realname" => $realname, "level" => 0 ); return \%monk; } sub promote { my $r_monk = shift; $r_monk->{level}++; }

Title edit by tye

Comment on Composition Examples Sought
Download Code
Re: Composition
by hagus (Monk) on May 24, 2002 at 01:00 UTC
    'Composition' as I understand it, simply refers to bringing in other objects to do tasks for you internally. Literally "an object inside another object".

    In C++ this takes place through protected or private inheritance, or making an object a member. Obviously just making it a normal member is the less idiomatic way. Using inheritance for that essentially exports the interface of the internal object to outside users of the class. You have to do that explicitly if you want it done at all, with normal membership composition.

    In Perl, I guess this would be something like $self->{obj} = new ObjectBlah; Simple as that.

    --
    Ash OS durbatulk, ash OS gimbatul,
    Ash OS thrakatulk, agh burzum-ishi krimpatul!
    Uzg-Microsoft-ishi amal fauthut burguuli.

      ...sorry still in the dark...

      I can see how it is possible to export an interface, but I don't see how to do the other side of that and make a new object who's methods are composed of (references?) to other objects...

        Like I said, Composition is having an object inside another object. Where you go from there with respect to *accessing* the nested object is up to you!

        package MainObject; sub new { ... $self->{nested} = new NestedObject; ... } sub callNestedObjectMethod { my $self = shift; $self->{nested}->theMethod; }
        But you might not even do that. You might never export 'theMethod' in this fashion, it might only be internally used. The 'Composition' part is having NestedObject as a member of your class.

        It sounds like what you want is to "take object a, b, c and make a new object that lets me call methods from all of them". That sounds like private/protected inheritance in C++, and that sounds messy. Why not explicitly write your interface as above?

        --
        Ash OS durbatulk, ash OS gimbatul,
        Ash OS thrakatulk, agh burzum-ishi krimpatul!
        Uzg-Microsoft-ishi amal fauthut burguuli.

Re: Composition
by perrin (Chancellor) on May 24, 2002 at 02:03 UTC
    Composition is usually viewed as an alternative to inheritance for code reuse. You can find a wealth of information on it with this Google search. It really has nothing to do with ObjectTemplate.pm, which is a fascinating piece of code but ultimately too slow to be very useful.
Re: Composition Examples Sought
by clemburg (Curate) on May 24, 2002 at 11:11 UTC

    From: Design Patterns: Elements of Reusable Object-Oriented Software, Gamma, Helm, Johnson, and Vlissides, Addison-Wesley, 1994. Page 18-20:

    The two most common techniques for reusing functionality in object-oriented systems are class inheritance and object composition. As we've explained, class inheritance lets you define the implementation of one class in terms of another's. Reuse by subclassing is often referred to as white-box reuse. The term "white-box" refers to visibility: With inheritance, the internals of parent classes are often visible to subclasses.

    Object composition is an alternative to class inheritance. Here, new functionality is obtained by assembling or composing objects to get more complex functionality. Object composition requires that the objects being composed have well-defined interfaces. This style of reuse is called black-box reuse, because no internal details of objects are visible. Objects appear only as "black boxes".

    ...

    That leads us to our second principle of object-oriented design: Favor object composition over class inheritance.

    Christian Lemburg

Re: Composition Examples Sought
by derby (Abbot) on May 24, 2002 at 12:24 UTC
    All great answers but to answer your question more directly:

    package Person; sub new { my $class = shift; my $type = ref($class) || $class; my $self = {}; $self->{name} = shift; $self->{password} = shift; $self->{realname} = shift; bless $self, $type; } package Monk; sub new { my $class = shift; my $type = ref($class) || $class; my $self = {}; $self->{person} = Person->new( @_ ); $self->{level} = 0; bless $self, $type; } sub promote { my( $self ) = shift; print "Brother ", $self->{person}{name}, " is getting some XP\n"; $self->{level}++; } 1;

    -derby

      /me has a bright light bulb floating above his head.
      Ahaaa! Now I see what's going on here.

      Thanks derby!!!

        This is what it looks like all together:
        #!/perl/bin/perl # package Person; sub new { my $class = shift; my $type = ref($class) || $class; my $self = {}; $self->{name} = shift; $self->{password} = shift; $self->{realname} = shift; bless $self, $type; } package Monk; sub new { my $class = shift; my $type = ref($class) || $class; my $self = {}; $self->{part1} = Person->new( @_ ); #One of the things things that +makes up a Monk is a Person $self->{level} = 0; bless $self, $type; } sub promote { my( $self ) = shift; print "Brother ", $self->{person}{name}, " is getting some XP\n"; $self->{level}++; } $monk1 = Monk::new("Monk","Darrel","mypass","Darrel Cusey"); print "Brother ", $monk1->{part1}{name}, " is level ", $monk1->{level} +,"\n"; promote($monk1); print "Brother ", $monk1->{part1}{name}, " is level ", $monk1->{level} +,"\n";;

        --
        I also like chicken.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://168941]
Approved by jarich
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others chilling in the Monastery: (9)
As of 2014-07-30 04:30 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My favorite superfluous repetitious redundant duplicative phrase is:









    Results (229 votes), past polls