- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
class Person
def one
@var = 99
self.two
end
private
def two
p @var
end
end
p=Person.new
p.one
当我运行此代码时,我收到错误消息main.rb:4:in one': 私有(private)方法
two' 调用 #
来自 main.rb:12:in `'
class Person
def one
@var = 99
two
end
private
def two
p @var
end
end
p=Person.new
p.one
当我运行这个时,我得到的输出为 99。因此,当 p.one 调用时,它会转到方法一,当它发现方法二没有任何接收者对象(这意味着方法二以 self 作为对象)时执行它,并且成功执行该方法。
但是当我手动给出 self.two 时,它给了我错误,为什么?
两个VS self.two的方法调用有什么区别?
最佳答案
why self.method_name cannot access private method ?
因为这就是 private
的定义方式,至少在您使用的旧版 Ruby 中是这样。
在当前版本的 Ruby 中可以。您所描述的行为仅存在于旧版本的 Ruby 中。
如果我使用我的 Ruby 安装(由 YARV 3.0.0 实现的 Ruby 3.0.0)运行您的代码,我不会收到错误。
以下是private
历史上的定义方式:
A
private
method can only be called without a receiver.
例如,参见 ISO/IEC 30170:2012 Information technology — Programming languages — Ruby specification 的第 13.3.5.3 节私有(private)方法 :
A private method cannot be invoked with an explicit receiver, i.e., a private method cannot be invoked if a primary-expression or a chained-method-invocation occurs at the position which corresponds to the method receiver in the method invocation
但是请注意,这并不是故事的全部。
在此规则下如何调用私有(private)属性编写器?答案是:你不能!您不能使用 self.foo = bar
因为您不允许使用显式接收器,并且您不能使用 foo = bar
因为这是对局部变量 foo
而不是对属性编写器 foo=
的调用。
所以,这个规则实际上有一个异常(exception):
A
private
method can only be called without a receiver, unless it is an attribute writer, then it can also be called with a receiver that is the literal pseudo-variableself
.
请注意,它必须是文字伪变量self
。它不能是计算结果为同一对象的任何任意表达式。
即这是允许的:
self.foo = bar
但这不是:
this = self
this.foo = bar
# private method `foo=' called for #<…> (NoMethodError)
ISO Ruby 语言规范的确切文本是:
A private method cannot be invoked with an explicit receiver, i.e., a private method cannot be invoked if a primary-expression or a chained-method-invocation occurs at the position which corresponds to the method receiver in the method invocation, except for a method invocation of any of the following forms where the primary-expression is a self-expression.
- single-method-assignment
- abbreviated-method-assignment
- single-indexing-assignment
- abbreviated-indexing-assignment
但是,这仍然不能解决所有问题:运算符怎么样,例如 self + bar
或 !self
?名称是诸如 class
之类的保留字的方法怎么样?
提议的规则变得越来越复杂。有关一些见解,请参阅以下有关 Ruby 问题跟踪器的讨论: Bug #9907 Abbreviated method assignment with private attr_writer
/attr_reader
does not work. [免责声明:我是提交该错误的人。]
要使此工作正常进行,您必须将规则更改为类似的内容
A
private
method can only be called without a receiver, unless it is an attribute writer or an operator, then it can also be called with a receiver that is the literal pseudo-variableself
, including in an abbreviated method assignment.
如您所见,规则变得相当复杂。
提出了一个更简单的规则,现在从 Ruby 2.7 开始实现:
self
to be called self.
现在的规则是:
A
private
method can only be called without a receiver or with an explicit receiver that is the literal pseudo-variableself
.
您可能会问自己,为什么不使用这个更简单的规则?
A
private
method can only be called with the receiverself
.
原因是旧规则、中间规则和新规则 can be decided statically, in fact even syntactically at parse time ,而这个非常简单的规则却不能。
关于ruby - 为什么 self.method_name 无法访问私有(private)方法?其中只有 private method_name 可以在任何方法中访问 ruby 中的私有(private)方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65867395/
我通过 spring ioc 编写了一些 Rest 应用程序。但我无法解决这个问题。这是我的异常(exception): org.springframework.beans.factory.BeanC
我对 TestNG、Spring 框架等完全陌生,我正在尝试使用注释 @Value通过 @Configuration 访问配置文件注释。 我在这里想要实现的目标是让控制台从配置文件中写出“hi”,通过
为此工作了几个小时。我完全被难住了。 这是 CS113 的实验室。 如果用户在程序(二进制计算器)结束时选择继续,我们需要使用 goto 语句来到达程序的顶部。 但是,我们还需要释放所有分配的内存。
我正在尝试使用 ffmpeg 库构建一个小的 C 程序。但是我什至无法使用 avformat_open_input() 打开音频文件设置检查错误代码的函数后,我得到以下输出: Error code:
使用 Spring Initializer 创建一个简单的 Spring boot。我只在可用选项下选择 DevTools。 创建项目后,无需对其进行任何更改,即可正常运行程序。 现在,当我尝试在项目
所以我只是在 Mac OS X 中通过 brew 安装了 qt。但是它无法链接它。当我尝试运行 brew link qt 或 brew link --overwrite qt 我得到以下信息: ton
我在提交和 pull 时遇到了问题:在提交的 IDE 中,我看到: warning not all local changes may be shown due to an error: unable
我跑 man gcc | grep "-L" 我明白了 Usage: grep [OPTION]... PATTERN [FILE]... Try `grep --help' for more inf
我有一段代码,旨在接收任何 URL 并将其从网络上撕下来。到目前为止,它运行良好,直到有人给了它这个 URL: http://www.aspensurgical.com/static/images/a
在过去的 5 个小时里,我一直在尝试在我的服务器上设置 WireGuard,但在完成所有设置后,我无法 ping IP 或解析域。 下面是服务器配置 [Interface] Address = 10.
我正在尝试在 GitLab 中 fork 我的一个私有(private)项目,但是当我按下 fork 按钮时,我会收到以下信息: No available namespaces to fork the
我这里遇到了一些问题。我是 node.js 和 Rest API 的新手,但我正在尝试自学。我制作了 REST API,使用 MongoDB 与我的数据库进行通信,我使用 Postman 来测试我的路
下面的代码在控制台中给出以下消息: Uncaught DOMException: Failed to execute 'appendChild' on 'Node': The new child el
我正在尝试调用一个新端点来显示数据,我意识到在上一组有效的数据中,它在数据周围用一对额外的“[]”括号进行控制台,我认为这就是问题是,而新端点不会以我使用数据的方式产生它! 这是 NgFor 失败的原
我正在尝试将我的 Symfony2 应用程序部署到我的 Azure Web 应用程序,但遇到了一些麻烦。 推送到远程时,我在终端中收到以下消息 remote: Updating branch 'mas
Minikube已启动并正在运行,没有任何错误,但是我无法 curl IP。我在这里遵循:https://docs.traefik.io/user-guide/kubernetes/,似乎没有提到关闭
每当我尝试docker组成任何项目时,都会出现以下错误。 我尝试过有和没有sudo 我在这台机器上只有这个问题。我可以在Mac和Amazon WorkSpace上运行相同的容器。 (myslabs)
我正在尝试 pip install stanza 并收到此消息: ERROR: No matching distribution found for torch>=1.3.0 (from stanza
DNS 解析看起来不错,但我无法 ping 我的服务。可能是什么原因? 来自集群中的另一个 Pod: $ ping backend PING backend.default.svc.cluster.l
我正在使用Hibernate 4 + Spring MVC 4当我开始 Apache Tomcat Server 8我收到此错误: Error creating bean with name 'wel
我是一名优秀的程序员,十分优秀!