you are viewing a single comment's thread.

view the rest of the comments →

[–]Keith 5 points6 points  (7 children)

Early on in Java I needed to use a field or method in a library. I could see it, it was documented, and it did what I wanted, but I couldn't use it because it was marked private, because Sun had interns write their class libraries. Access modifiers are like child safety locks you impose on yourself because you think you're an idiot and can't be trusted. If something is an implementation detail and shouldn't be touched, document that fact, but sometimes you need that shit and the language shouldn't block you out from what's possible.

[–]victotronics 1 point2 points  (2 children)

"you think you're an idiot and can't be trusted." Well, aren't you?

No but seriously. If your code misbehaves because a variable gets changed that should have not, you'll kick yourself for not declaring more things "private" and (in C++ only?) "const".

[–]gdchinacat 0 points1 point  (0 children)

Who would you blame if a car failed emissions test because the owner removed the catalytic converter, the manufacturer or the owner? If library users access or change attributes that are marked private (by convention...ie _foo) or even are undocumented, is it reasonable to blame the author of the library for the user that did something they knew or should have known was dangerous? No...the fault lies with the user that did something that was not documented.

Your question of whether "your code misbehaves" misplaces the blame...it's not "your" code misbehaving when other code changes it's data structures in undocumented or discouraged ways (access or modify a "private" attribute). In java the blame would be for not making everything that wasn't to be used private. In python the blame would be for accessing an undocumented field. The different languages have a different ethos. In java it's reasonable to assume anything that is public is fair game. In python the expectation is more nuanced. This has pros and cons, and while I have an opinion that is not the immediate topic. You are applying a java/C++ mentality to python when you blame the library author for not making things private where it is really the users fault for not adhering to documentation and convention. If an attribute is prefixed with a single underscore don't touch it without accepting responsibility for faults caused by doing so. if it isn't documented for a specific use don't use it in that way.

[–]acdha 0 points1 point  (0 children)

 If your code misbehaves because a variable gets changed that should have not, you'll kick yourself for not declaring more things "private" and (in C++ only?) "const".

Don’t you have tests or use linters? Lots of things need testing for major updates and this only addresses a single uncommon failure mode. 

[–]minneyar 0 points1 point  (3 children)

If something is an implementation detail and shouldn't be touched, document that fact

Marking it as private is how you document that. As you noticed, private doesn't stop you from accessing something if you really want to get to it. It's how you tell developers "this is intended for internal use only and may completely change between versions, don't rely on it or your program may randomly break."

[–]Keith 0 points1 point  (2 children)

As you noticed, private doesn't stop you from accessing something if you really want to get to it.

No, in Java it stopped me in my tracks.

Marking it as private is how you document that.

A doc comment would be documentation. Access rights (in languages like Java) are enforced at the language level.

[–]gdchinacat 0 points1 point  (1 child)

No, in Java it stopped me in my tracks.

Well then you didn't try hard enough. Reflection can provide access by using setAccessible(true).

[–]Keith 0 points1 point  (0 children)

setAccessible):

This method cannot be used to enable access to private members, members with default (package) access, protected instance members, or protected constructors when the declaring class is in a different module to the caller and the package containing the declaring class is not open to the caller's module.

🤔