Reading through some old posts I've run into multiple mentions of the idea that "accessors break encapsulation". (See here, for example.) I think this idea has some merit for languages like C++ or Java in which one can assign levels of privacy to methods, and thereby enforce one's published API, although it would have to be rephrased as "public accessors break encapsulation".

But with Perl it's not so easy to enforce a distinction between the published API and a class's private methods. For the vast majority of published classes I've looked at, "private" methods are simply those that are not explicitly described in the official documentation. If someone finds out what these unpublished methods are, e.g. by reading the source code, he/she can use them. (Of course, this is a bad idea, but my point is that, in this common situation, Perl provides no encapsulation, other than that granted through "the kindness of strangers".)

I find accessors are useful internally, for the same reason they are useful externally: they provide insulation against whatever changes may affect the implementation of a state variable. Therefore, even when I don't publish most accessors, I like to have plenty of them (I usually give these "private" accessors names that begin with _, FWIW).

Of course, I could do the "lexical accessors" trick (i.e. implement accessors as coderefs stored in lexical variables), but this is problematic in two ways. One is that subclasses cannot inherit these accessors, which, more often than not is a PITA. And two, I can't directly test these "lexical accessors" in my test suite.

This last point brings up another important question, entirely orthogonal to the accessors issue: should a test suite test only the published API, or should it also test private methods? In my view, the utility of a test suite for refactoring is greatly diminished if it doesn't test private methods... I suppose that a module could include some internal tests that can have access to module-private lexicals, but I digress.

As always, I look forward to reading your comments.

Update: Added a "?" after the title. Added link to Hollub's article.

the lowliest monk


In reply to "Accessors break encapsulation"? by tlm

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.