public/protected/private is a dumb idea in dynamic languages. If you don't want someone calling your method, prefix it with an underscore and say "the results are undefined if you call methods that start with an underscore". Done. Easier to maintain, easier to test, less code to type in.
Come to think of it... public/protected/private is a dumb idea in C++ and Java, too.
> public/protected/private is a dumb idea in dynamic languages.
PHP is mostly a static language; it has more in common with Java than with say Ruby.
> prefix it with an underscore
Oh god, really. Next you'll be telling us we don't need namespaces, we can just use an underscore as a separator!
> and say "the results are undefined if you call methods that start with an underscore". Done. Easier to maintain, easier to test, less code to type in.
Or you could just build that all into the language itself so it's self documenting and provides a nice concise error message when used incorrectly!
I'm amazed that people would argue for naming conventions over actual features. Hell, nobody is saying you have have to use it; if you'd rather use underscores the languages will let you.
A few things about PHP, Java, and Ruby: PHP, Java, and Ruby are all compiled to byte code before executed. Java and Ruby are strongly typed languages. PHP and Ruby are dynamically typed languages (no explicit variable declarations). Ruby and PHP are compiled when run but Java is compiled ahead of time.
But significant to my point: Ruby classes are created at runtime but PHP and Java classes are created at compile time. This is why you can't, with runtime code, alter the structure of a class in PHP or Java.
No kidding, I hate having to write some reflection BS in C# just to call a 'private method' as if addresses in memory cared about such things. The worst is some of the MS extensions for WIN32 that have private constructors designed to prevent obvious functionality. (Basically the constructors are private for political reasons). IIRC, it was something to do with reading COM streams from .msg files. It really ticked me off.
Dynamic or not, objects have interfaces and this is a way of defining the public interface and catching violations of it.
> Easier to maintain, easier to test, less code to type in
My impression is opposite. They add friction to changing visibility. I like to start with everything private and then unprotect as needed.
It's extra character to type and it interferes with autocomplete.
Accessibility of "private" methods shouldn't be help in tests — you'll end up creating tests that depend on implementation. If class is too impenetrable to test, then refactor it (split concerns, add dependency injection, etc.), don't unprotect it.
Recently at my company we're writing a lot of JS and its' lack of "public/protected/private" doesn't make it easier to maintain or test. Actually, it's quite frustrating because you know you can't test it properly - everything public? it's a ticking timebomb, someone at some point will simply override your method somewhere and hell will broke loose
Even though JS doesn't have language constructs for public/private, there are a number of different ways to write modules with hidden members by use of closures.
I'd say that using closures and functions to create public apis with internal private structure does qualify it to have 'language constructs for public/private'.
It just took programmers collectively over 10 years to figure it out. I blame the 'new' keyword in JS, it feels completely grafted on after the fact.
Lua has been using this method of designing modular programs for years.
I know you can do it, but it produces quite an overhead and it's ugly. But that's for another discussion ("sad things in JS" maybe) - here my main point was that, no, public/protected/private is not a dumb idea in dynamic languages.
I wrote a simple library based off of Crockford's writings to make creating reusable constructor functions that supported public/protected/private simple (and without resorting to silly "if it's preceded with an underscore don't touch it!" business). It was written mainly with Node.js in mind, but you could strip out the CommonJS package stuff and use it that way.
Agreed. When I started using python I thought that I would miss protected/public methods, but I was wrong. Conventions are the better solution and make testing incredibly easier.
Totally agree. Of course, because PHP has the public/protected/private idea, it's correct in not redefining those for its own meaning, so the complaint is missing the point.
I think the worst villains of the public/protected/private family are getter/setter methods, it bugs me when I see them in Python code. We use enunciate ( http://enunciate.codehaus.org ) at work, and we bundle AMF endpoints with our stuff. Unfortunately the Java-to-actionscript step complained when our data objects don't have getters/setters (since I like just using public attributes), so now I have two Python scripts: one generating the Java code for a data object along with annotations, the other adding getter/setter methods.
Come to think of it... public/protected/private is a dumb idea in C++ and Java, too.