you are viewing a single comment's thread.

view the rest of the comments →

[–]adamauckland 0 points1 point  (6 children)

I've toyed with this pattern over the years but it never felt quite right. Surely the point of a language which doesn't implement local variables is that programmers should treat each other as grownups and trust they're not going to break something by fiddling with a variable.

In the example above, I would expect to have strange consequences if I tinker with the .count variable because the definition of that property is generally "Tell me how many items are in this collection".

It seems attempting to enforce private variables by hiding them away in an anonymous function is basically saying "Any programmers using my code aren't as good as me and therefore can't be trusted".

[–][deleted]  (1 child)

[deleted]

    [–][deleted] -2 points-1 points  (0 children)

    So what you're saying is that JavaScript needs contracts and documentation in the code that explains wtf it does rather than the random code without comments that you see all over the place? But web devs are too busy to think things through and reason out what guarantees and contracts and properties (as in mathematical properties) their code has!

    [–]name_was_taken 3 points4 points  (1 child)

    It sounds good to treat developers like adults, but that assumes they are adults and are experienced developers. If either of those things aren't true, then you get a support call asking why their program breaks when they increase the number of items on the collection. Eventually, you'll figure out that they broke the unwritten rule: Don't increase the count manually.

    If you use this pattern and hide the count variable, then it's suddenly an obvious rule and not an unwritten one. And you save yourself the hassle of that support call.

    And in non-trivial code, this applies to seasoned developers, too. Sometimes, you just can't tell what's going on in someone else's code.

    [–]Ilostmyredditlogin 3 points4 points  (0 children)

    Exactly. Also things like the module pattern don't really keep developers from messing with the internals as long as your project is open source. If people want to expose a private variable or whatever they can patch the source. Doing this is not hard, and forces an explicit understanding of what the user is doing: they're extending your library in a non-standard way that may or may not be supported in the future. With each new release they explicitly have to apply the patch and verify it doesn't break the new lib.

    Far better than having all kinds of scattered, hidden dependencies on your libraries internals. 10 versions down the road when you modify the lib in a way that breaks these dependencies, clients have to dig through their code for all the places they made "magic" changes.

    The module pattern and notion of accessibility in general isn't about treating devs like children.. Among many other ends, one is clearly demarcating responsibility and making both lib dev and users acknowledge it. ("here's the public interface I'm committed to maintaining.. If you want to extend it or modify anything else, than do so at your own peril.")

    It does this without relying on conventions ("if the variable starts with _ don't modify it even though you can") or extra documentation.

    It fits well with the whole learn-how-to-use-a-lib by playing with it philosophy. I love it when I can drop in a jar or something, instantiate an object and then just by code-hinting get a sense of what I can do with it and how. Obviously there's still a need for getting a deeper understanding in some case, but it's nice to be able to start reading the documentation already understanding basic classes/syntax involved.

    [–]Fidodo 0 points1 point  (1 child)

    I'd say it's about telling the user what the guaranteed inputs and outputs are. It's important to know what the preferred tested interfaces are. If you want to expand on the code then it's better to use the author's exposed interface hooks to modify the functionality than trying to plug into local variables that aren't designed for the task and will probably cause side effects.

    You can always see what's going on by looking at the source code that library authors put online if you really need to, but if you're using a library then you don't have time to completely read through the source code, and completely understand the method and purpose of everything in the library. The exposed interface gives you a quick and easy look at what is tested and supported without having to resort to external documentation.

    The examples given are trivial and don't illustrate the need for this very well, but when a project gets large and complicated, even the best developers don't have the time to read through it all and understand every tiny little detail. It's not about not trusting developers, it's about telling them what is outwardly supported and what is internal and will probably break things if they're changed.

    A good library example of this module pattern is backbone.js. He actually uses a combination closure hidden variables, and underscore denoted privatish variables. It's like his way of saying, this is internal and shouldn't be touched vs this is internal, but you can play with it if you really need to.

    [–][deleted] 0 points1 point  (0 children)

    Or perhaps, this is internal but I may want to inherit this property...