NAME

Devel::EnforceEncapsulation - Find access violations to blessed objects

SYNOPSIS

package BankAccount;
sub new {
   my $pkg = shift;
   return bless {}, $pkg;
}
sub balance {
   my $self = shift;
   return $self->{balance};
}
# ... etc. ...

package main;
Devel::EnforceEncapsulation->apply_to('BankAccount');
my $acct = BankAccount->new();
print $acct->balance(),"\n";  # ok
print $acct->{balance},"\n";  # dies

LICENSE

Copyright 2006 Clotho Advanced Media, Inc., <cpan@clotho.com>

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

DESCRIPTION

Encapsulation is the practice of creating subroutines to access the properties of a class instead of accessing those properties directly. The advantage of good encapsulation is that the author is permitted to change the internal implementation of a class without breaking its usage.

Object-oriented programming in Perl is most commonly implemented via blessed hashes. This practice makes it easy for users of a class to violate encapsulation by simply accessing the hash values directly. Although less common, the same applies to classes implemented via blessed arrays, scalars, filehandles, etc.

This module is a hack to block those direct accesses. If you try to access a hash value of an object from it's own class, or a superclass or subclass, all goes well. If you try to access a hash value from any other package, an exception is thrown. The same applies to the scalar value of a blessed scalar, entry in a blessed array, etc.

To be clear: this class is NOT intended for strict enforcement of encapsulation. If you want bullet-proof encapsulation, use inside-out objects or the like. Instead, this module is intended to be a development or debugging aid in catching places where direct access is used against classes implemented as blessed hashes.

To repeat: the encapsulation enforced here is a hack and is easily circumvented. Please use this module for good (finding bugs), not evil (making life harder for downstream developers).

METHODS

Class::Encapsulate::Runtime->apply_to($other_pkg);
Class::Encapsulate::Runtime->remove_from($other_pkg);

Add or remove strict encapsulation to an existing $other_pkg.

SEE ALSO

Class::Encapsulate is a proposed module by Curtis "Ovid" Poe (not yet on CPAN as of this writing) that will provide a production-ready implementation of this technique.

Class::InsideOut, Object::InsideOut and Class::Std are all implementations of "inside-out" objects, which offer a stricter encapsulation style at the expense of a less familiar coding style.

DIAGNOSTICS

"Illegal attempt to access %s internals from %s"

(Fatal) You tried to access a hash property directly instead of via an accessor method. The %s values are the object and caller packages respectively.

QUALITY

We care about code quality. This distribution complies with the following quality metrics:

  • Perl::Critic v0.20 passes

  • Devel::Cover test coverage at 100%

  • Pod::Coverage at 100%

  • Test::Spelling passes

  • Test::Portability::Files passes

AUTHOR

Clotho Advanced Media Inc., cpan@clotho.com

Maintainer: Chris Dolan

CREDITS

This idea, and the original source code, came from Adrian Howard via Curtis "Ovid" Poe on http://www.perlmonks.org/?node_id=576707|perlmonks.org. Adrian has authorized me to release a variant of his code under the Perl license.

Joshua ben Jore suggested some great improvements that significantly simplified yet generalized the implementation. http://use.perl.org/comments.pl?sid=33253&cid=50863