Kar*_*k T 6 ruby overriding operators
测试代码:
class PrivHash < Hash
def set(key, val)
self[key] = val
end
def set_maybe(key, val)
self[key] ||= val
end
private
def []= key, value
end
def [] key
super
end
end
Run Code Online (Sandbox Code Playgroud)
有了这个代码,我都期盼set和set_maybe工作.但是,只有set工作并set_maybe失败:
[30] pry(#<TranslationInfo>):1> ph.set_maybe(:a, 1)
NoMethodError: private method `[]' called for {:a=>2}:#Class:0x007f99c5924c38>::PrivHash
from (pry):56:in `set_maybe'
Run Code Online (Sandbox Code Playgroud)
我认为这self[:b] ||= <x>只是语法糖self[:b] || self[:b] = <x>,但我想这不是因为这有效.
什么错误我是为什么我得到这个错误..我从类中执行此,所以为什么我得到私有方法错误?
目前,私有方法的处理有点混乱。
原来的规则是:
私有方法只能在没有显式接收者的情况下调用。
这是一个很好的、简单的、容易理解的规则。它也是一个静态规则,即不需要运行代码就可以检查,事实上,它甚至是一个语法规则,它甚至不需要复杂的静态分析,可以在解析器中检查。
然而,很快人们就注意到,这条规则使得调用私有 setter 变得不可能,因为没有显式接收者就无法调用 setter(foo = bar是设置局部变量,而不是调用 setter)。因此,规则被扩展:
私有方法只能在没有显式接收器的情况下调用,除非方法调用是赋值方法调用,在这种情况下,只要显式接收器是文字伪变量,也可以使用显式接收器调用该方法
self。
这允许您使用文字值的显式接收器调用私有设置器self:
self.foo = bar
Run Code Online (Sandbox Code Playgroud)
但不是动态值self
baz = self
baz.foo = bar # NoMethodError: private method `foo=' called
Run Code Online (Sandbox Code Playgroud)
这仍然保留了可以在解析时检测到私有方法调用的属性。
两年前,我提交了一个关于缩写方法分配不起作用的错误,即:
self.foo += bar # NoMethodError
Run Code Online (Sandbox Code Playgroud)
通过再次扩展私有方法调用的规则来修复该错误(现在规则已经变得如此复杂,我不打算详细说明)。
然而,仍然有很多情况没有被现有规则涵盖,这些方法在语法上根本无法在没有显式接收者的情况下被调用,因此不能是私有的:
self[foo]
!self
self + foo
Run Code Online (Sandbox Code Playgroud)
ETC。
其中一些已经修复,一些还没有。问题是该规则现在变得如此复杂,以至于很难正确实施。有人建议将规则更改为如下内容:
私有方法只能在没有显式接收器或显式接收器(即字面量伪变量)的情况下调用
self。
这是一个很好、简单、易于理解的规则,可以在解析时进行静态检查,并且没有我们当前拥有的复杂异常和极端情况。然而,据我所知,它尚未实施。
| 归档时间: |
|
| 查看次数: |
74 次 |
| 最近记录: |