在隐式接收器上调用 * 方法
Call * method on implicit receiver
我想创建下一个 DSL 部分:
* 'Ruby'
下一个实验显示了可预测的结果:
def *(a)
a
end
* 'Ruby' #=> SyntaxError: (irb):4: syntax error, unexpected '\n', expecting :: or '[' or '.'
self.*(1) #=> NoMethodError: private method `*' called for main:Object
self.send(:*, 1) #=> 'Ruby'
我想 Ruby 语法分析器将这样的表达式视为 splat 运算符或星号方法的语法糖。有人可以更详细地解释一下并(如果可能的话)提供解决方案来解决我的问题吗?
这不可能。有一些方法在没有显式接收者的情况下根本无法调用,否则它们会产生歧义。特别是,在同时具有一元前缀和二元中缀运算符的每种情况下,都不可能区分这两种情况:
+ a == a.+@()
- a == a.-@()
& a # interpreted as the unary prefix proc-block conversion operator
* a # interpreted as the unary prefix splat operator
或者在运算符与其他语法冲突的情况下:
/ a # interpreted as the start of a Regexp literal
为了保持一致性,Ruby 强制对 所有 二元中缀运算符使用两个操作数,而不仅仅是那些语法不明确的操作数。
同样,[]
不能在没有显式接收者的情况下调用,因为它会与数组的文字语法冲突。
另一个 well-known 没有显式接收器就无法调用的方法示例是设置器:
self.foo = bar # setter
foo = bar # local variable
对于 private
设置器,private
方法的规则实际上有一个例外,允许使用显式接收者调用它们,只要该显式接收者是文字 pseudo-variable关键字self
。但是,调用私有二元运算符或 []
等方法不存在此类异常。 (不过,有这方面的建议。)
Jörg W Mittag 回答了为什么您的第一个表达式 * 'Ruby'
(没有显式接收者)会引发错误。
我将补充为什么您的第二个表达式 self.*(1)
(具有显式接收者)会引发错误。这是因为方法定义在main
对象上,默认都是私有的
这告诉你调用该方法的唯一方法是既不带也不不带显式接收者,换句话说,你不能以普通方法调用的形式调用该方法。您只能以描述该方法的符号形式传递它,并让另一个方法(send
)执行它。
我想创建下一个 DSL 部分:
* 'Ruby'
下一个实验显示了可预测的结果:
def *(a)
a
end
* 'Ruby' #=> SyntaxError: (irb):4: syntax error, unexpected '\n', expecting :: or '[' or '.'
self.*(1) #=> NoMethodError: private method `*' called for main:Object
self.send(:*, 1) #=> 'Ruby'
我想 Ruby 语法分析器将这样的表达式视为 splat 运算符或星号方法的语法糖。有人可以更详细地解释一下并(如果可能的话)提供解决方案来解决我的问题吗?
这不可能。有一些方法在没有显式接收者的情况下根本无法调用,否则它们会产生歧义。特别是,在同时具有一元前缀和二元中缀运算符的每种情况下,都不可能区分这两种情况:
+ a == a.+@()
- a == a.-@()
& a # interpreted as the unary prefix proc-block conversion operator
* a # interpreted as the unary prefix splat operator
或者在运算符与其他语法冲突的情况下:
/ a # interpreted as the start of a Regexp literal
为了保持一致性,Ruby 强制对 所有 二元中缀运算符使用两个操作数,而不仅仅是那些语法不明确的操作数。
同样,[]
不能在没有显式接收者的情况下调用,因为它会与数组的文字语法冲突。
另一个 well-known 没有显式接收器就无法调用的方法示例是设置器:
self.foo = bar # setter
foo = bar # local variable
对于 private
设置器,private
方法的规则实际上有一个例外,允许使用显式接收者调用它们,只要该显式接收者是文字 pseudo-variable关键字self
。但是,调用私有二元运算符或 []
等方法不存在此类异常。 (不过,有这方面的建议。)
Jörg W Mittag 回答了为什么您的第一个表达式 * 'Ruby'
(没有显式接收者)会引发错误。
我将补充为什么您的第二个表达式 self.*(1)
(具有显式接收者)会引发错误。这是因为方法定义在main
对象上,默认都是私有的
这告诉你调用该方法的唯一方法是既不带也不不带显式接收者,换句话说,你不能以普通方法调用的形式调用该方法。您只能以描述该方法的符号形式传递它,并让另一个方法(send
)执行它。