gpt4 book ai didi

ruby - 覆盖散列并使 [] 运算符私有(private) - 不能再使用 ||=

转载 作者:数据小太阳 更新时间:2023-10-29 07:05:01 26 4
gpt4 key购买 nike

测试代码:

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

使用此代码,我希望 setset_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'

我假设 self[:b] ||= <x>只是 self[:b] || self[:b] = <x> 的语法糖,但我想这不是因为它有效。

让我感到困扰的是为什么我会收到此错误。我是从类中执行的,所以为什么会收到私有(private)方法错误?

最佳答案

目前,私有(private)方法的处理有些困惑。

原始规则是:

private methods can only be called without an explicit receiver.

这是一个很好的、简单的、容易理解的规则。它也是一个静态规则,即它可以在不运行代码的情况下进行检查,事实上,它甚至是一个语法规则,它甚至不需要复杂的静态分析, 它可以在解析器中检查。

但是,很快就注意到这条规则使得调用私有(private) setter 变得不可能,因为没有显式接收者就无法调用 setter(foo = bar 是设置局部变量,而不是调用二传手)。因此,规则被扩展:

private methods can only be called without an explicit receiver, unless the method call is an assignment method call, in which case the method can also be called with an explicit receiver as long as that explicit receiver is the literal pseudo-variable self.

这允许您使用字面值 self 的显式接收者调用私有(private) setter:

self.foo = bar

但不是self的动态值

baz = self
baz.foo = bar # NoMethodError: private method `foo=' called

这仍然保留了可以在解析时检测到私有(private)方法调用的属性。

两年前,I filed a bug关于缩写方法分配不起作用,即:

self.foo += bar # NoMethodError

通过再次扩展私有(private)方法调用的规则修复了该错误(现在规则已经变得如此复杂以至于我不打算详细说明)。

但是,仍然有很多情况没有被现有规则涵盖,其中方法在没有显式接收者的情况下根本无法在句法上被调用,因此不能是私有(private)的:

self[foo]
!self
self + foo

等等

有些已经修复,有些还没有。问题是规则现在变得如此复杂以至于很难正确实现。 There have been proposals to change the rule像这样:

private methods can only be called without an explicit receiver or an explicit receiver which is the literal pseudo-variable self.

这是一个很好、简单、易于理解的规则,可以在解析时进行静态检查,并且没有我们目前遇到的任何复杂异常和极端情况。但是,它尚未实现 AFAIK。

关于ruby - 覆盖散列并使 [] 运算符私有(private) - 不能再使用 ||=,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37129767/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com