微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

ruby – 覆盖哈希并将[]运算符设为私有 – 不能再使用|| =

测试代码
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

使用此代码,我希望set和set_maybe都能正常工作.但是,只有set works和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'

我假设自己[:b] || =< x>只是自我的语法糖[:b] || self [:b] =< x&gt ;,但我想这不是因为这有效. 什么错误我是为什么我得到这个错误..我从类中执行此,所以为什么我得到私有方法错误

解决方法

目前,处理私有方法有点乱.

最初的规则是:

private methods can only be called without an explicit receiver.

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

然而,很快就注意到这个规则使得无法调用私有setter,因为没有显式接收器就不能调用setter(foo = bar是设置局部变量,而不是调用setter).因此,规则扩大了:

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的显式接收器调用私有setter:

self.foo = bar

但不是自我的动态价值

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

这仍然保留了在分析时可以检测到私有方法调用属性.

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

self.foo += bar # NoMethodError

通过再次扩展私有方法调用的规则来修复该错误(现在规则已经变得如此复杂,以至于我不会拼出它).

但是,仍有很多案例未被现有规则所涵盖,其中方法在没有显式接收器的情况下根本无法在语法上调用,因此不能是私有的:

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.

原文地址:https://www.jb51.cc/ruby/264701.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐