当我在 IRB 中声明时,为什么我的顶级方法 public(相对于私有)在所有 类 上?
Why is my top-level method public (as opposed to private) on all classes when I declare it in IRB?
我正在阅读 "The Well-Grounded Rubyist",在第 196 页我看到以下内容:
Suppose you define a method at the top level:
def talk
puts "Hello"
end
....
A method that you define at the top level is stored as a private
instance method of the Object
class. The previous code is
equivalent to this:
class Object
private
def talk
puts "Hello"
end
end
...
To illustrate, let's extend the talk
example. Here it is again,
with some code that exercises it:
puts "Trying 'talk' with no receiver..."
talk
puts "Trying 'talk' with an explicit receiver..."
obj = Object.new
obj.talk
The first call to talk
succeeds; the second fails with a fatal
error, because it tries to call a private method with an explicit
receiver.
我想在我的本地复制这个,所以我把上面的代码放在我创建的 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 解释器 运行ning 代码相同的错误:
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
是一个 public 方法在 Object
实例上。
我的问题是 - 为什么 talk
方法 public 在对象 class 上直接在 REPL 中实现它,但在文件中实现它时是私有的并且将它加载到 REPL 中(以及当我通过 Ruby 解释器直接在我的 CLI 中 运行 相同的文件时)?
irb
和pry
(旁注:我强烈建议使用后者)调整他们的输入以将所有方法声明为public(在 E
阶段 REP
循环):
▶ def foo; end
#⇒ :foo
▶ public_methods.grep /foo/
#⇒ [:foo]
就是这样,没有魔法。
这样做主要是为了简化在此处定义方法然后希望可以从例如那里。在 REPL
让一切随处可用是值得的。
def pretty_print; self.inspect; end
class A; ...; end
class B; ...; end
A.new.pretty_print
B.new.pretty_print
玩沙盒的时候不要太在意封装、SRP等问题
一般来说,这就像用通用助手声明模块并免费将其包含在任何地方。
我正在阅读 "The Well-Grounded Rubyist",在第 196 页我看到以下内容:
Suppose you define a method at the top level:
def talk puts "Hello" end
....
A method that you define at the top level is stored as a private instance method of the
Object
class. The previous code is equivalent to this:class Object private def talk puts "Hello" end end
...
To illustrate, let's extend the
talk
example. Here it is again, with some code that exercises it:puts "Trying 'talk' with no receiver..." talk puts "Trying 'talk' with an explicit receiver..." obj = Object.new obj.talk
The first call to
talk
succeeds; the second fails with a fatal error, because it tries to call a private method with an explicit receiver.
我想在我的本地复制这个,所以我把上面的代码放在我创建的 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 解释器 运行ning 代码相同的错误:
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
是一个 public 方法在 Object
实例上。
我的问题是 - 为什么 talk
方法 public 在对象 class 上直接在 REPL 中实现它,但在文件中实现它时是私有的并且将它加载到 REPL 中(以及当我通过 Ruby 解释器直接在我的 CLI 中 运行 相同的文件时)?
irb
和pry
(旁注:我强烈建议使用后者)调整他们的输入以将所有方法声明为public(在 E
阶段 REP
循环):
▶ def foo; end
#⇒ :foo
▶ public_methods.grep /foo/
#⇒ [:foo]
就是这样,没有魔法。
这样做主要是为了简化在此处定义方法然后希望可以从例如那里。在 REPL
让一切随处可用是值得的。
def pretty_print; self.inspect; end
class A; ...; end
class B; ...; end
A.new.pretty_print
B.new.pretty_print
玩沙盒的时候不要太在意封装、SRP等问题
一般来说,这就像用通用助手声明模块并免费将其包含在任何地方。