Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

Encapsulation as aid to debugging

by chrisdolan (Beadle)
on Oct 06, 2006 at 20:44 UTC ( #576754=note: print w/replies, xml ) Need Help??


in reply to Better Inside-Out Objects :)

Rather than focus on the inside-outness (which, as others have commented, is questionable) how about thinking about this as a "strict" mode for object accesses. Below is a modified version of the above code, optimized for catching attempts to break encapsulation. It croaks if an external caller tries to access hash values directly.
{ package Encapsulate; use Scalar::Util; use Carp; my $Secrets = {}; use overload '%{}' => sub { my $obj = shift; my $caller_pkg = caller; my $pkg = ref $obj; if ( !$pkg->isa( $caller_pkg ) && !$caller_pkg->isa( $pkg )) { croak "Illegal attemp to access $pkg " . "internals from $caller_pkg"; } my $id = Scalar::Util::refaddr( $obj ); return $Secrets->{ $id } ||= {}; }, fallback => 1; sub DESTROY { my $id = Scalar::Util::refaddr( shift ); delete $Secrets->{ $id }; } } { package Foo; use base qw( Encapsulate ); sub new { my $class = shift; return bless {}, $class; } sub foo { my $self = shift; $self->{ secret } = shift if @_; return $self->{ secret }; } } { package Bar; use base qw( Foo ); sub bar { my $self = shift; $self->{ secret } = shift if @_; return $self->{ secret }; } } { package Quux; use base qw( Encapsulate ); sub new { my $class = shift; return bless {}, $class; } sub foo { my $self = shift; $self->{ secret } = shift if @_; return $self->{ secret }; } } use Test::More tests => 7; my $o = Bar->new; isa_ok $o, 'Bar'; $o->foo( 42 ); is $o->foo, 42, "can set and get value of Foo's secret"; Bar->new->foo( 24 ); is $o->foo, 42, "different objects get different secrets"; Quux->new->foo( 24 ); is $o->foo, 42, "different classes get different secrets"; $o->bar( 99 ); is $o->bar, 99, "can set and get value of Bar's secret"; is $o->foo, 99, "secrets of subclasses are shared"; eval { $o->{secret}; }; ok $@, 'cannot reach into objects';

Replies are listed 'Best First'.
Re: Encapsulation as aid to debugging
by mreece (Friar) on Oct 06, 2006 at 22:30 UTC
    $o->bar( 99 ); is $o->bar, 99, "can set and get value of Bar's secret"; is $o->foo, 99, "secrets of subclasses are shared";
    can you explain the intent there? why should setting bar also change foo?

      foo and bar aren't properties. They're both alias accessors to a single, private property called secret.

      -xdg

      Code written by xdg and posted on PerlMonks is public domain. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others rifling through the Monastery: (1)
As of 2019-08-21 01:43 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?