Mark24
记录灵感、技术、思考
Ruby私有方法 getter 可以显示指定 self 接收者
原帖内容:《Ruby 私有方法 getter 为什么可以显示指定接收者了?(和书上不一样)》
《Ruby 程序员修炼之道》、《Ruby 基础教程(第五版)》 都在强调,一旦方法被设置为 private,getter 是无法显示声明调用者的。
为什么我可以显示声明 self.egg, 它还能工作?书写错了?
代码如下:
class Baker
def work
puts "---work---"
puts "--egg-getter--"
self.egg
puts "---set egg--"
self.egg=555
puts '--self.egg--'
self.egg
puts '---just egg--'
egg
end
private
def egg
puts "--egg--getter--"
@egg ||= 0
end
def egg=(value)
puts "--setter--getter--"
@egg = value
end
end
运行
➜ ruby-test git:(master) ✗ ruby -v
ruby 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [x86_64-linux] # 我的ruby版本
➜ ruby-test git:(master) ✗ irb -r './private.rb' --prompt simple
>> b=Baker.new
>> b.egg # private getter方法,直接调用会报错,正常
Traceback (most recent call last):
3: from /home/mark24/.asdf/installs/ruby/2.7.1/bin/irb:23:in `load'
2: from /home/mark24/.asdf/installs/ruby/2.7.1/lib/ruby/gems/2.7.0/gems/irb-1.2.3/exe/irb:11:in `<top (required)>'
1: from (irb):2
NoMethodError (private method `egg' called for #<Baker:0x000055c96a887898>)
>> b.egg=999 # private setter 方法,直接调用会报错,正常
Traceback (most recent call last):
5: from /home/mark24/.asdf/installs/ruby/2.7.1/bin/irb:23:in `<main>'
4: from /home/mark24/.asdf/installs/ruby/2.7.1/bin/irb:23:in `load'
3: from /home/mark24/.asdf/installs/ruby/2.7.1/lib/ruby/gems/2.7.0/gems/irb-1.2.3/exe/irb:11:in `<top (required)>'
2: from (irb):2
1: from (irb):3:in `rescue in irb_binding'
NoMethodError (private method `egg=' called for #<Baker:0x000055c96a887898>)
>> b.work # public 方法,直接调用
---work---
--egg-getter--
--egg--getter-- # 这不对呀,应该报错才对呀
---set egg--
--setter--getter--
--self.egg--
--egg--getter--
---just egg--
--egg--getter--
=> 555
>>
经过我的不懈努力终于找到了。
也就是所有书里面(过时了)
对于 Private 方法的 getter 不可以显示 self 调用,要改写了。
https://www.ruby-lang.org/en/news/2019/12/25/ruby-2-7-0-released/
Calling a private method with a literal self as the receiver is now allowed.
[Feature #11297], [Feature #16123]
def foo
end
private :foo
self.foo