in reply to subclass data clobbering superclass data

Hi princepawn.

RecentChanges told me that something happened with AnonymousSubroutineObjects and I noticed the referer link here.

You've commented on the most dispised node on perldesignpatterns.com. Okey, the second most dispised. ImplicitThis is the most dispised. FlowCharts is the most popular node. Go figure.

"this node", a.k.a. AnonymousSubroutineObjects is primarily an example of using lexical scoping to save having to explicitly pass data to a constructor. An object can be created in the lexical context which the data exists. It touches on other things, such as the lack of AttributeInheritance in Perl, as summed up in HowDoesPerlStackUp. This is really a HowDoesPerlStackUp topic.

To answer your question, OO languages normailly provide a few levels of protection. These levels of protection are idiomatic for different situations.

1. public. Everyone can count on the continued existance of this fascility, be it an InstanceVariable or an Accessor. Help yourself. goto TOWN.

2. protected. Subclasses can diddle it. Subclasses are going to have more dependancy on their parent class than other classes will. They have more need to dig into its guts and diddle it. In order to make the base class useful as a base class, these protected bits need to be opened up to subclasses, though, so they officially become part of the interface for the object - but only the interface that subclasses need concern themselves with.

3. private. No one, and that means no one, should be mucking with this bit of entrail. Not inheriting subclasses, no one. This is likely to change. The programmer might be sitting in his office chair right now stewing about how badly he hates how he implemented this fascily and is biding his time to completely change it before people notice how awful it is and form an opinion of his work. He probably resents his employer for forcing the deadline that prompted that cheezeball solution. Elegance is ready and waiting, but not walking down the isle.

Perl doesn't force these things. Unless you do it manually using PrivateFunctions or something similar. 99 out of 100 cases, I suggest you don't. I do suggest you understand why this is done in other langauges and document your code with this understanding. And maintain your interfaces with this knowledge.

Too hard-core for me, there is a principe of OO design. In order to not introduce bugs into existing, working code, all design should be "open and shut". After an object is written, it is only ever edited to fix blatent bugs (not design bugs, only implementation bugs) or as part of refactoring. And I'm not an Ivory tower OO programmer either - and I make a case for not being one in various places, including PlanningIsNpComplete. Again, it is educational to understand and then elect your own level of stricture or protocol - sometimes very little, some times loads. This open and shut approach leaves specialization - and in the case of AbstractRootClasses, the actual implementation - to subclasses. Just like you suggested. By not going back and tweaking one object, you're not going to break other objects that depend on its behavior, even if the behavior seems odd. The only time an interface is diddled is when a refactoring happens, and as you know, refactorings are a very controlled thing, done one careful step at a time. Atleast that is how this story goes. You don't do NoseJobRefactoring, do you? Of course not. Even though this wall is erected between the superclass and the subclass, the subclass has enough room to do its thing - by design - and privacy and encapsulation is maintained.

As far as "overwrite superclass data", I'd stop there. If a subclass can't have its own private data, you run into namespace conflicts. When a superclass intentionally means to share data, it should be available, of course of course. When it doesn't mean to share data, well, you get back into the turf where erecting walls and demanding privacy is helpful. If none of this makes a whit of sense to you, you haven't worked on an extremely large project with hundreds of programmers. You may not have worked on one where there were dozens. You look the other way, and everything has changed out from under you. Things put one way for a specific reason are changed. The way things are doesn't make sense and there is no explanation but if you change it, things might break. Whether something is even intentional or not is unclear. Whether some code constitutes a commitment to do something one way or whether it is merely a first attempt at sounding out a preliminary pass is a mystery, blowing in the wind. You spend all of your time in email and trying to figure out why something that you had working the other day doesn't work today. Unless very careful bounds are drawn. And enforced. Levels of protection provide just this.

This may never affect you. Especially if Perl is your primary or only language. But programming as if it does can make your Perl better. Programming as if you understand the cases where it might affect someone can make your Perl truely great. But no promises. Programming like you are aware of the issues means that you might one day be allowed to program, when the regeim change is finished, Perl doesn't exist any more, and everything is Java or C#. No, seriously, having an understanding of how and why this comes into play opens a lot of doors. Programming shops want to know that you'll work on a team, and this is _the_ issue. That and hygeine. Language isn't one. No one answers emails. They just counter attack with more and more restrictive levels of protection, keeping those grubby hands off their fine working code.

-scott
  • Comment on Re: subclass data clobbering superclass data