in reply to Closure objects with public, private, and protected fields

From the TMTOWTDI dept.:

My CPAN distro, KinoSearch, is a loose port of the Java search engine library Lucene. At 70+ modules, it's a large system, so enforcing access levels is important. However, watertight access level control in Perl takes heroics, and heroics are expensive both in terms of maintenance and CPU time.

The policy I came up with (text taken from KinoSearch::Docs::DevGuide), is only a mild expansion on widespread Perl practices. It's served me well so far:

No public member variables.

Multiple classes defined within a single source-code file, e.g. TermQuery and TermWeight, may use direct access to get at each others member variables. Everybody else has to use accessor methods.

C-struct based classes such as TermInfo allow direct access to their members, but only from C (of course).

Subroutine/method access levels

There are three access levels in KinoSearch.

  1. public: documented in "visible" pod.
  2. private: subs which are prepended with an _underscore may only be used within the package in which they reside -- as per perlstyle guidelines -- and in only one source file.
  3. distro: any sub which doesn't fall into either category above may be used anywhere within the KinoSearch distribution.

The ban on public member variables, plus some lightweight constructor argument checking, goes pretty far towards insulating KinoSearch against autovivification problems and all the rest. If there were a public API for getting at the C struct members, I'd hide them behind accessors using C function pointers, but since there's not, compile-time checking provides sufficient internal protection.

I haven't really needed protected methods. The ACL that would be handy is what they call "package" in Javaland, but I couldn't use that name for it because packages in Perl have a smaller scope, and "distro" is my imperfect substitute.

KinoSearch is currently about half/half C-struct based XS classes and hash-based classes, with a smattering of inside-out classes. I'd consider changing the internal implementation of the hash-based classes to inside-out if I thought it was important. But defining ACLs in the private API beyond what I'm doing now would be overkill, while tagging some visible methods as "protected" would just confuse a lot of Perlers.

--
Marvin Humphrey
Rectangular Research ― http://www.rectangular.com
  • Comment on Re: Closure objects with public, private, and protected fields

Replies are listed 'Best First'.
Re^2: Closure objects with public, private, and protected fields
by thor (Priest) on Mar 05, 2006 at 14:05 UTC
    At 70+ modules, it's a large system, so enforcing access levels is important.
    In my opinion, you're drawing a conclusion based on an irrelevant metric. You either need access control or you don't. Chances are that you don't, but if you feel that you need it, don't feel that you also have to justify it; it's your code. :)

    thor

    The only easy day was yesterday

      Thor, please elaborate on why "chances are" there's no need for access control in a system that big. Perhaps you interpreted the word "enforcing" in an absolute sense? This is open source: all access control is advisory.

      Exposing a member variable in a public API has the disadvantage of freezing an implementation detail. Standard OO theory says that's probably not a good idea in either large or small systems. The distinction between large and small is in the internal API -- it's more important that components in a large system do not violate encapsulation of other components.

      Say you have only two small hash-based classes in your distro and one accesses a hash member in the other directly. When you refactor and change the name of that variable, you can just check the other file and be sure that there aren't any ill consequences. In a large system, that's not feasible because it's prohibitively time-consuming and difficult to inspect all the code in the project every time you change an implementation detail. However, with the ACL policy I have in place, I can change how any hash member or leading-underscore sub behaves and feel confident that I only have to check the file I'm currently editing.

      --
      Marvin Humphrey
      Rectangular Research ― http://www.rectangular.com
        My point is that if you use anything but the publicly defined interface, you take your life into your own hands. Make the interface to each class clean and you don't have to worry about breaking people that don't use it. I don't feel bad if I break the code of someone who relied on a non-public interface to one of my classes. Some people don't understand that you don't need things like protected or private.

        As an aside, the openness or closedness of the source has little to do with this conversation. There are plenty of open source Java programs that must implement the class control mechanisms mentioned above because that's the way that that language works. In its current incarnation, Perl has no such notions.

        thor

        The only easy day was yesterday