【发布时间】:2017-01-03 09:15:36
【问题描述】:
我有两个班级Foo 和Bar:
require 'pry-byebug'
require 'fileutils'
class Foo < Pathname
include FileUtils
def initialize(path)
puts "Inside Foo init..."
super
puts "Side effect happening..."
end
def some_method
puts "Inside some_method inside Foo..."
basename.to_s
end
end
class Bar < Foo
end
bar = Bar.new('bar')
# binding.pry
bar.some_method
这是输出:
Inside Foo init...
Side effect happening...
Inside some_method inside Foo...
Inside Foo init...
Side effect happening...
如您所见,“副作用”发生了两次。查看pry-byebug 会话确认:
Inside Foo init...
Side effect happening...
From: /Users/max/Dropbox/work/tmp/super_test/foo.rb @ line 23 :
18: class Bar < Foo
19: end
20:
21: bar = Bar.new('bar')
22: binding.pry
=> 23: bar.some_method
[1] pry(main)> step
From: /Users/max/Dropbox/work/tmp/super_test/foo.rb @ line 13 Foo#some_method:
12: def some_method
=> 13: puts "Inside some_method inside Foo..."
14: basename.to_s
15: end
[1] pry(#<Bar>)> step
Inside some_method inside Foo...
From: /Users/max/Dropbox/work/tmp/super_test/foo.rb @ line 14 Foo#some_method:
12: def some_method
13: puts "Inside some_method inside Foo..."
=> 14: basename.to_s
15: end
[1] pry(#<Bar>)> step
From: /Users/max/Dropbox/work/tmp/super_test/foo.rb @ line 7 Foo#initialize:
6: def initialize(path)
=> 7: puts "Inside Foo init..."
8: super
9: puts "Side effect happening..."
10: end
所以分解它:
- 我实例化了
bar,它是Bar的一个实例,它继承自Foo。Bar's superclass'initialize被调用并且“副作用”发生。到目前为止,这完全是意料之中的。 - 我在
bar上给some_method打电话,谁没有它,所以ruby 向右移动,在Foo内部找到它 - Ruby 跳转到
some_method内部并找到一个向self发送消息的方法,称为basename - Ruby 回到
Foo's'initialize方法?...
第 4 步完全出乎我的意料。为什么向self 发送消息会导致再次调用初始化方法?这在任何地方都有记录吗?这是预期的吗?
可以控制吗?或者有条件地检查我是否在初始化方法中,因为我实际上是在实例化一个类而不是随机登陆那里?例如:
class Foo < SomeClass
def initialize args
@args = args
if instantiating_a_class?
puts "Side effect happening..."
else
puts "Don't do anything..."
end
end
end
【问题讨论】: