4 ms·
> then parse the completely un-parsable output to know which keys can decrypt the file. This reminds me so much about a tip in Effective Java .. 'Always provi
by sgift 8y ago
> then parse the completely un-parsable output to know which keys can decrypt the file.
This reminds me so much about a tip in Effective Java .. 'Always provide an option for users to access every relevant part of your object. If not people will start to parse your toString output and you will have created an inofficial API that you have to support whether you want or not' (paraphrased from my faulty memory). That programmers make that mistake again and again is just sad. :(
- speedplane 8y agoThis is what I love about Python. Every method is public, but methods that start with an underscore mean "use at your own risk". It suggests that the programmer use a preferred way, without strictly requiring it. Private methods treat programmers like infants.
- sgift 8y agoIME if you allow someone to use your private API you can be sure they will do at some point. And then they will be unhappy when you change it. Sure, you can go with "I said it was private, your problem", but that is the road to zero users.
- tjohns 8y agoSo much this. I've seen it happen time and time again. At least in Java, the reflection API serves as a "break glass" barrier to make sure folks understand they're doing something they shouldn't. Someone will still do it, and they'll still blame you when their app breaks later... but I like to believe it at least scares some folks away.
- speedplane 8y agoHonestly, I don't see people getting unhappy at breaking private API functionality. Most grab a library when they need and never upgrade it. They only do so when there's a necessary security risk or some wiz-bang new feature they need. The common example: programmer grabs a library to solve a problem; a few weeks later they realize it doesn't really solve the problem and requires modifications to the library to do some custom job; they make the modifications. That's normally the end of the story for several years. No point in upgrading the library unless it really solves a business problem. That constitutes the vast majority of developers. Of course there are other organizations that always want the latest and greatest version and are constantly upgrading. To them, I'd say sure, stick to the public methods, otherwise you're creating a big headache down the road. But I wouldn't require it of them.
- simias 8y agoIMO there's a difference between "use at your own risk" and "this is actually not meant to be called from the outside and if it is it will violate some invariant in the code". Those are two different concepts and it makes sense to distinguish them. Of course in high level highly managed languages like python it makes sense that the difference between the two can be rather fuzzy at times but in low level code there's often a clear difference. Take for instance a socket class in C++, you might have a private method that deals with the low level details of the libc's socket calls. It's called at construction time and never later, and calling it would cause the current socket to be replaced by the new one (leaking the fd in the process) because it's only meant to be used at init time. Clearly it's not "use at your own risk", it's "code that calls this from the outside is fundamentally broken". Having the compiler enforce this invariant is a useful feature. Meanwhile you can also have "use at your own risk" methods, for instance "get_raw_fd" if you want to be able to access the underlying socket. It makes it easy to break things but has legitimate use cases. Of course you could say that you could just tag these private in a certain way and let coder discipline do the rest, but then again you could say that of pretty much all static validation (which, I suppose, makes sense if you like very dynamic languages like Python).
- Sean1708 8y ago> IMO there's a difference between "use at your own risk" and "this is actually not meant to be called from the outside and if it is it will violate some invariant in the code". Those are two different concepts and it makes sense to distinguish them. That's what double underscores are for: $ python3 Python 3.5.2 (default, Nov 23 2017, 16:37:01) [GCC 5.4.0 20160609] on linux Type "help", "copyright", "credits" or "license" for more information. >>> class Foo: ... def foo(self): ... print("I'm a public method.") ... def _foo(self): ... print("I'm a private method.") ... def __foo(self): ... print("I'm so private that you have to really know what you're doing to even call me.") ... >>> foo = Foo() >>> foo.foo() I'm a public method. >>> foo._foo() I'm a private method. >>> foo.__foo() Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'Foo' object has no attribute '__foo' >>> foo._Foo__foo() I'm so private that you have to really know what you're doing to even call me. >>> Now in theory it's not quite what you're talking about because it does rely on coder discipline to some extent, but in practice I've never seen it become an issue (although arguably that could be because not many people know that you can access double underscore variable from outside a class).
- TheCoelacanth 8y agoClosed source dependencies treat programmers as infants. With open source dependencies, private methods are just an organization tool, not an actual limitation on the programmer.
- speedplane 8y agoIf a programmer cannot access some variable or function because another developer thought that they "shouldn't", how is that not treating them like infants?
- zaarn 8y agoGPG is largely just this toString output parsing. Which has been the source of a number of bugs in various GPG clients in the past (a few even on the HN frontpage for a few moments) and probably will into the future until GPG is no longer used. tbh, GPG should just provide an RPC option so applications can securely pass data back and forth and receive proper error messages and codes. But I bet this won't happen because GNU fears that sort of things considering they won't split up the GCC compiler.
- scandox 8y agoWell there is GPGME: https://gnupg.org/software/gpgme/index.html https://gnupg.org/software/gpgme/index.html But yes I mostly parse colon separated text.
- admax88q 8y ago> But I bet this won't happen because GNU fears that sort of things considering they won't split up the GCC compiler. That's unfounded, there are plenty of GNU projects that have an API.
- zaarn 8y agoIt's not unfounded. The GCC compiler isn't splitting up because they fear someone would build a proprietary compiler using either backend or frontend API if they did it. I can see that the same reasoning here would be valid; someone could write a proprietary GPG frontend.
- admax88q 8y agoYou have one example of a project not providing an API, however there are tons of other GNU projects which do. Furthermore the GCC decision is well documented in mailing list posts, have you ever seen anyone involved in GPG development claim that they won't allow a library/frontend split for fear of someone writing a proprietary frontend?
- doesnt_know 8y agoHyrum's Law With a sufficient number of users of an API, it does not matter what you promise in the contract: all observable behaviors of your system will be depended on by somebody. http://www.hyrumslaw.com/ http://www.hyrumslaw.com/ I'm in a team where all the consumers are only other internal teams and yet this still happens. I've found that it doesn't matter if you explicitly state to not rely on a particular behavior in your documentation, clients still will. It's always your fault if you break it because "it was your change that broke this client" and "it was working fine yesterday".
- Nae3Au5x 8y agoSome people may depend on them, but the difference between API guarantees and implementation details is that developers are far less reluctant to break your legs... I mean your application if you depend on the latter. For example in java the iteration order of hash maps or the behavior of sorts in presence of non-reflexive comparators changed and people did depend on that. Sun was able to change it because it was not part of the API contract.
- pure-awesome 8y agoMan, depending on sort order with a non-reflexive comparator is a TERRIBLE idea. Almost on the level of https://xkcd.com/1172/ https://xkcd.com/1172/