TE
科技回声
首页24小时热榜最新最佳问答展示工作
GitHubTwitter
首页

科技回声

基于 Next.js 构建的科技新闻平台,提供全球科技新闻和讨论内容。

GitHubTwitter

首页

首页最新最佳问答展示工作

资源链接

HackerNews API原版 HackerNewsNext.js

© 2025 科技回声. 版权所有。

Ruby's private keyword is weird

109 点作者 jez超过 1 年前

10 条评论

dmurray超过 1 年前
The other approach to private methods is weird.<p>It breaks the object-oriented paradigm. Why should my Dog be able to check out the internal StomachContents of another Dog, while that information isn&#x27;t available to a Vet or even to the Dog&#x27;s Owner?<p>Possibly the Dog can even check out the StomachContents of a Wolf or an Elephant, depending on your language and your inheritance rules. Even if the Dog otherwise has no relation to the second animal.<p>It&#x27;s because we&#x27;re seeing behind the curtain. The internal implementation of method Fido.vomit() is some equivalent of Dog::vomit(Fido) so the current object isn&#x27;t actually in as privileged a position as it might appear to a reader. The language privileges all members of class Dog instead.<p>Ruby has the same problem even more, because the first thing any Ruby library author does is to monkeypatch everyone else&#x27;s objects. It solves it in the opposite way, by really trying to make the language know when an object is calling a method on itself, but again the implementation leaks and the language runtime can&#x27;t always know that. Which is fine - Ruby&#x27;s philosophy is to provide convenient escape hatches for this kind of thing anyway, and to limit you by convention rather than by compiler errors.
评论 #38652693 未加载
评论 #38652753 未加载
评论 #38653006 未加载
评论 #38652948 未加载
stouset超过 1 年前
I’ve only glanced quickly at the article, but I think the author’s understanding of private in Ruby is wrong.<p><pre><code> class Parent attr_accessor :x private :x def initialize(x) self.x = x # └── (1) allowed end def ==(other) self.x == other.x # │ └── (2) not allowed # └── (1) allowed end end </code></pre> This is not doing what the author thinks it is doing. Or, it is, but I don’t think the authors understand why. `private :x` <i>only marks the x method as private</i>, but `x=` is a different method.<p>They would see different behavior with<p><pre><code> private :x private :x= </code></pre> In general, public, private, and protected do the following. Public methods can be called with <i>any</i> receiver: explicit (x.foo()), self (self.foo()), or implicit (foo()). Protected methods can be invoked on self or with an implicit receiver. Private methods can only be invoked on an implicit receiver. Note that this has <i>nothing to do</i> with the class hierarchy. A private method can be called from a subclass as long as it has an implicit receiver.<p>The difference between protected and private is not really practically useful, so I personally use them to signal different levels of “private-ness”. I use protected methods to implement a class’ “internal API”, which is the core thing the public API is abstracting and exposing. I use private methods for implementing ancillary details that aren’t really core to what the class does but handle some one-off unrelated data manipulation or munging. But that’s just me.<p>I’ll also admit that something may have changed with Ruby’s rules around these keywords around 3.0 that I missed, so if that’s the case I apologize.
评论 #38650530 未加载
评论 #38654431 未加载
aardvark179超过 1 年前
Ruby&#x27;s behaviour is weird if you&#x27;re used to many other OO languages, but it shares that weirdness with other languages influenced by Smalltalk, such as the Magik languages used in the Smallworld GIS.<p>Both ideas of what private means make sense, but I can certainly understand the confusion they cause if you expect one behaviour and discover your language does something different.
评论 #38653772 未加载
lmm超过 1 年前
Some of the reason for Scala having `private[this]` is that it allows an implementation that behaves (and performs) like a Java private field. Scala fields generally aren&#x27;t raw fields at the JVM level (because of Scala&#x27;s &quot;uniform access principle&quot; that `def x` should be accessible like `val x`), but private[this] fields allow the compiler to represent them as raw fields since they really can&#x27;t be accessed elsewhere.<p>The only other thing I&#x27;m aware of being allowed to go in the[] part of a Scala access modifier is a containing package (or object?), which allows you to emulate Java&#x27;s &quot;default&quot; (AKA &quot;package-private&quot;) visibility.
评论 #38651711 未加载
kevincox超过 1 年前
Python takes an interesting approach that mimics the behaviour of statically-typed languages without static typing.<p>If you have a member that starts with `__` then it gets rewritten. For example&#x27;s sake let&#x27;s say that `self.__x` in class `Parent` becomes `__Parent_x`. Also note that because the resulting name starts with `__` as well you can&#x27;t easily just do this mangling yourself as writing `p.__Parent_x` in class `Other` will result in `p.__Other_Parent_x`. (But you can easily access via something like `getattr(p, &quot;__Parent_x&quot;)`). This means that `self.__x == that.__x` will desugar to something like `self.__Parent_x == that.__Parent_x` so you will be able to access privates of other members of the same class. It also means that subclasses won&#x27;t be able to access private members because `self.__x` will become `self.__Child_x`.<p>IIUC JavaScript has something similar for `this.#x`. Although this is implemented much more robustly and doesn&#x27;t rely on unique class names and I believe is actually &quot;secure&quot; as in no other class can gain access. But I am not up-to-date on JS reflection abilities. The code desugars to something like `const X_PROP = new Symbol()` created once-per-class and accessible only to the class itself, then the accesses become something like `this[X_PROP]`.
评论 #38656454 未加载
评论 #38669494 未加载
LesZedCB超过 1 年前
yes this makes sense because ruby is a message passing language. even accessors are messages. only self can receive private messages.<p>and the sharing a private instance variable between separate instances example is exactly what protected does, which ruby also has.
评论 #38650357 未加载
评论 #38650597 未加载
3np超过 1 年前
&gt; So far, I’m only aware of Ruby’s private modifier and Scala’s protected[this] which behave like this. If you know of any other languages, please email me! I’d love to hear about them.<p>Rerouting throgh comments: Event if it&#x27;s very different, TypeScript&#x27;s private has quite surprising semantics as well...
评论 #38669503 未加载
uticus超过 1 年前
I’ll add to existing comments that it might also be interesting to look through conversations re Smalltalk. Ruby was influenced by Smalltalk, so interesting to note in Smalltalk it is impossible to have private methods.<p><a href="https:&#x2F;&#x2F;stackoverflow.com&#x2F;q&#x2F;7399340" rel="nofollow noreferrer">https:&#x2F;&#x2F;stackoverflow.com&#x2F;q&#x2F;7399340</a><p><a href="http:&#x2F;&#x2F;computer-programming-forum.com&#x2F;3-smalltalk&#x2F;5139b6267b2d0b78.htm" rel="nofollow noreferrer">http:&#x2F;&#x2F;computer-programming-forum.com&#x2F;3-smalltalk&#x2F;5139b6267b...</a><p>…etc
thayne超过 1 年前
protected[this] was removed in scala 3[0]. And honestly, I can&#x27;t think of a case where it was really useful.<p>[0]: <a href="https:&#x2F;&#x2F;docs.scala-lang.org&#x2F;scala3&#x2F;reference&#x2F;dropped-features&#x2F;this-qualifier.html" rel="nofollow noreferrer">https:&#x2F;&#x2F;docs.scala-lang.org&#x2F;scala3&#x2F;reference&#x2F;dropped-feature...</a>
评论 #38656395 未加载
furyofantares超过 1 年前
&gt; The member x cannot be accessed in subclasses of Parent, like Child<p>This is a typo and should say &quot;can&quot;, right?
评论 #38656406 未加载