我当前正在阅读“ The Well-Grounded Rubyist”,在第196页上,我看到以下内容:
假设您在顶层定义了一个方法:
def talk puts "Hello" end
....
您在顶层定义的方法存储为私有方法
Object
类的实例方法。之前的代码是 等效于此:class Object private def talk puts "Hello" end end
...
为说明起见,让我们扩展
talk
示例。又来了 带有一些执行它的代码:puts "Trying 'talk' with no receiver..." talk puts "Trying 'talk' with an explicit receiver..." obj = Object.new obj.talk
对
talk
的第一次调用成功;第二个失败并致命 错误,因为它尝试使用显式调用私有方法 接收器。
我想在本地复制它,所以将上面的代码放在我创建的Ruby文件中。我确实得到了书中提到的结果:
$ ruby talk.rb
Trying 'talk' with no receiver...
Hello
Trying 'talk' with an explicit receiver...
Traceback (most recent call last):
talk.rb:22:in `<main>': private method `talk' called for #<Object:0x00007f9a8499c3e0> (NoMethodError)
我还尝试了以下方法,产生了与通过Ruby解释器运行代码相同的错误:
irb(main):008:0> load 'talk.rb'
Trying 'talk' with no receiver...
Hello
Trying 'talk' with an explicit receiver...
Traceback (most recent call last):
4: from /Users/richiethomas/.rbenv/versions/2.5.3/bin/irb:11:in `<main>'
3: from (irb):8
2: from (irb):8:in `load'
1: from talk.rb:22:in `<top (required)>'
NoMethodError (private method `talk' called for #<Object:0x00007ffb219c95e0>)
接下来,我在irb
中尝试了相同的代码,这次我得到了以下奇怪的结果:
irb(main):001:0> def talk
irb(main):002:1> puts "Hello"
irb(main):003:1> end
=> :talk
irb(main):004:0> puts "Trying 'talk' with no receiver..."
Trying 'talk' with no receiver...
=> nil
irb(main):005:0> talk
Hello
=> nil
irb(main):006:0> puts "Trying 'talk' with an explicit receiver..."
Trying 'talk' with an explicit receiver...
=> nil
irb(main):007:0> Object.new.talk
Hello
=> nil
如您所见,在上一个代码示例中,我能够调用Object.new.talk
并将其打印为Hello
,就像.talk
是{{1}上的公共方法一样}实例。
我的问题是-为什么在我直接在REPL中实现Object
方法时,它在Object类上是公共的,而当我在文件中实现并将其加载到REPL中时(以及当我通过Ruby解释器直接在我的CLI中运行该文件)?
答案 0 :(得分:1)
irb
和pry
(边注:我强烈建议使用后者)调整其输入以将所有方法声明为公共方法(在 {{1 }} E
循环的阶段):
REP
就是这样,没有魔术。
这样做的目的主要是为了简化在以下情况下的使用过程:当一个人在此处定义该方法,然后希望可以从例如那里。在▶ def foo; end
#⇒ :foo
▶ public_methods.grep /foo/
#⇒ [:foo]
中,使所有地方都可以访问是值得的。
REPL
在玩沙盒时,不要太在意封装,SRP等。
通常,这就像使用通用助手声明该模块,并在所有地方免费包含它。