in reply to Conventions with Passing Objects to Objects

In general it's fine to store one object inside another as you are doing. However, there is an issue with stuff like this: Quote:
Inside Object2: sub setsomething { my $self = shift; $self->{_object1}->{mode} = 1; }
What this means is that you have given Object2 some "inside knowledge" of how Object1 is implemented, because Object2 is "reaching inside" Object1's hash to get the "mode" key. This is considered bad. You, or someone else, might decide to change the implementation of Object1 -- maybe you'll decide to call "mode" something else, or even that Object1 should use an arrayref instead of a hashref for performance reasons. Then Object2 will break. Clean object encapsulation requires that you hide implementation details from other objects, and present only an API for them to use. What this means is you have to provide an accessor function in Object1 like this:
sub mode { my $self = shift; $self->{mode} = $_[0] if (@_); $self->{mode}; }
And then in Object2, instead of
$self->{_object1}->{mode} = 1;
you use
$self->{_object1}->mode(1);
The main advantages: a) You are free to change the internal implementation of Object1 without affecting Object2. b) You can choose to perform additional tasks in Object1 when mode is set, or read. Even choose to deny access. Writing accessor functions by hand is tedious though, so it's good to use something like Class::Accessor, or weave some magic with AUTOLOAD and a _permitted list.

Replies are listed 'Best First'.
Re^2: Conventions with Passing Objects to Objects
by zxViperxz (Acolyte) on Jan 20, 2006 at 06:36 UTC
    Thanks for pointing this out, I've noticed that I have recently started falling into this trap as I've become more experienced with Objects. I will make sure I stear clear of it in the future. Thanks, James.