ruby – 为什么不能使用符号来调用protected方法?
给出以下类:
class Foo def a dup.tap { |foo| foo.bar } end def b dup.tap(&:bar) end protected def bar puts 'bar' end end 似乎Foo#a和Foo#b应该是等效的,但是它们不是: > Foo.new.a bar => #<Foo:0x007fe64a951ab8> > Foo.new.b NoMethodError: protected method `bar' called for #<Foo:0x007fe64a940a88> 有没有理由呢?这是一个bug吗? 测试了Ruby 2.2.3p173 解决方法
让我们从Ruby开始,你可能知道,在Foo类中声明的方法中,我可以在任何Foo实例上调用受保护的方法.
Ruby如何确定我们是否处于Foo类中声明的方法?要理解这一点,我们必须深入研究方法调用的内部.我将使用2.2版本的MRI中的示例,但推测其行为和实现在其他版本中是一样的(我希望看到在JRuby或Rubinious上进行测试的结果). Ruby在 块有点混淆.请记住,Ruby方法中的局部变量由该方法中声明的任何块捕获.这意味着在块中,self是调用该方法的同一个自身.我们来看一个例子: class Foo def give_me_a_block! puts "making a block,self is #{self}" Proc.new do puts "self in block0 is #{self}" end end end proc = Foo.new.give_me_a_block! proc.call 运行这个,我们看到Foo的相同实例在所有级别都是一样的,即使我们从完全不同的对象调用proc. 所以,现在我们明白为什么可以在一个方法的一个块内从同一个类的另一个实例上调用一个protected方法. 现在我们来看看为什么用&:bar创建的proc不能这样做.当我们放置&在方法参数之前签名,我们做两件事情:指示ruby将此参数作为块传递,并指示它调用to_proc. 这意味着调用Symbol#to_proc的方法.该方法在C中实现,但是当我们调用C方法时,当前帧上的指向self的指针将成为该C方法的接收者 – 在这种情况下,它成为符号:bar.所以我们正在看一下我们得到的foo实例,就好像我们在类Symbol中的方法一样,我们不能调用一个protected方法. 这是一口气,但希望它足够有意义.如果您有任何建议,如何改善它,请告诉我们! (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |