<P>A lexical variable is visible only through the end of its static scope.
That means that the only code able to access that variable is code
residing textually below the <A HREF="../../lib/Pod/perlfunc.html#item_my"><CODE>my()</CODE></A> operator through the end of its block
if it has one, or through the end of the current file if it doesn't.</P>
<P>Starting again with our simplest example given at the start of this
document, we replace <A HREF="../../lib/Pod/perlfunc.html#item_our"><CODE>our()</CODE></A> variables with <A HREF="../../lib/Pod/perlfunc.html#item_my"><CODE>my()</CODE></A> versions.</P>
<PRE>
package Some_Class;
my($CData1, $CData2); # file scope, not in any package
sub CData1 {
shift; # XXX: ignore calling class/object
$CData1 = shift if @_;
return $CData1;
}
sub CData2 {
shift; # XXX: ignore calling class/object
$CData2 = shift if @_;
return $CData2;
}</PRE>
<P>So much for that old $Some_Class::CData1 package variable and its brethren!
Those are gone now, replaced with lexicals. No one outside the
scope can reach in and alter the class state without resorting to the
documented interface. Not even subclasses or superclasses of
this one have unmediated access to $CData1. They have to invoke the &CData1
method against Some_Class or an instance thereof, just like anybody else.</P>
<P>To be scrupulously honest, that last statement assumes you haven't packed
several classes together into the same file scope, nor strewn your class
implementation across several different files. Accessibility of those
variables is based uniquely on the static file scope. It has nothing to
do with the package. That means that code in a different file but
the same package (class) could not access those variables, yet code in the
same file but a different package (class) could. There are sound reasons
why we usually suggest a one-to-one mapping between files and packages
and modules and classes. You don't have to stick to this suggestion if
you really know what you're doing, but you're apt to confuse yourself
otherwise, especially at first.</P>
<P>If you'd like to aggregate your class attributes into one lexically scoped,
composite structure, you're perfectly free to do so.</P>
<PRE>
package Some_Class;
my %ClassData = (
CData1 => "",
CData2 => "",
);
sub CData1 {
shift; # XXX: ignore calling class/object
$ClassData{CData1} = shift if @_;
return $ClassData{CData1};
}
sub CData2 {
shift; # XXX: ignore calling class/object
$ClassData{CData2} = shift if @_;
return $ClassData{CData2};
}</PRE>
<P>To make this more scalable as other class attributes are added, we can
again register closures into the package symbol table to create accessor
methods for them.</P>
<PRE>
package Some_Class;
my %ClassData = (
CData1 => "",
CData2 => "",
);
for my $datum (keys %ClassData) {
no strict "refs";
*$datum = sub {
shift; # XXX: ignore calling class/object
$ClassData{$datum} = shift if @_;
return $ClassData{$datum};
};
}</PRE>
<P>Requiring even your own class to use accessor methods like anybody else is
probably a good thing. But demanding and expecting that everyone else,
be they subclass or superclass, friend or foe, will all come to your
object through mediation is more than just a good idea. It's absolutely
critical to the model. Let there be in your mind no such thing as
``public'' data, nor even ``protected'' data, which is a seductive but
ultimately destructive notion. Both will come back to bite at you.
That's because as soon as you take that first step out of the solid
position in which all state is considered completely private, save from the
perspective of its own accessor methods, you have violated the envelope.
And, having pierced that encapsulating envelope, you shall doubtless
someday pay the price when future changes in the implementation break
unrelated code. Considering that avoiding this infelicitous outcome was
precisely why you consented to suffer the slings and arrows of obsequious
abstraction by turning to object orientation in the first place, such