我需要猴子补丁文件。Timecop不影响文件系统报告的时间,这是File.atime使用的,而HttpClient在将文件发送到服务器时又使用这个时间,这又意味着VCR不完全按需要工作。AFAIK,这意味着我不能使用改进。
我不明白这是怎么回事
class File
def atime
"this one happens"
end
end
module CoreExtensions
module File
module TimecopCompat
def atime
"this one does not"
end
end
end
end
File.include CoreExtensions::File::TimecopCompat
File.new('somefile').atime # --> "this one happens"为什么基于模块的猴子补丁不发生?我需要改变什么才能让它发挥作用?我应该用的是另一种猴子贴图吗?
发布于 2019-07-26 19:24:10
这个问题与include将模块附加到祖先链的方式有关。"Ruby模块:包括vs Prepend和扩展“非常详细地概述了include和prepend之间的差异。
看看这两个例子:
class Foo
def hello
"1"
end
end
module Bar
def hello
"2"
end
end
Foo.include Bar
Foo.new.hello
# => "1"
Foo.ancestors
# => [Foo, Bar, Object, Kernel, BasicObject]对比
class Foo
def hello
"1"
end
end
module Bar
def hello
"2"
end
end
Foo.prepend Bar
Foo.new.hello
# => "2"
Foo.ancestors
# => [Bar, Foo, Object, Kernel, BasicObject]基本上,您希望在您的情况下使用prepend,因为include不会覆盖现有的方法。
发布于 2019-07-26 19:50:40
include不是什么神奇的东西。实际上,它非常简单:它使模块成为它混入的类的超类。现在:超类方法是否覆盖子类方法?不,当然不是,情况正好相反。
因此,include不可能覆盖模块要进入的类的方法。
这就是prepend的作用所在,它在祖先层次结构开始时混合在一个模块中。(不幸的是,不能简单地用继承来解释,这是另一回事。)
发布于 2019-07-26 21:24:44
让我们在不改变问题的情况下简化您的示例。
module TimecopCompat
def atime
"this one does not"
end
end我没有使用类File,因为它已经有一个实例方法File#atime。
File.new('temp').atime
#=> 2019-07-16 20:20:51 -0700正如其他答案所解释的,执行
File.include TimecopCompat在以下方面的成果:
File.ancestors
#=> [File, TimecopCompat, IO, File::Constants, Enumerable, Object, Kernel, BasicObject]
File.new('temp').atime
#=> 2019-07-16 20:20:51 -0700而执行
File.prepend TimecopCompat在以下方面的成果:
File.ancestors
#=> [TimecopCompat, File, IO, File::Constants, Enumerable, Object, Kernel, BasicObject]
File.new('temp').atime
#=> "this one does not" 然而,改变任何核心方法的行为是很糟糕的做法,因为它的原始行为可能依赖于程序的其他部分。
这里有两种可以接受的做法。第一种方法是创建一个方法(new_atime,例如),该方法的参数是File对象(file,例如):
file = File.new('temp')
x = new_atime(file)new_atime不能以一个File对象作为它的接收方,但是为了一个安全和健壮的解决方案,这是一个很小的代价。
第二个选项是使用精练来refine File类。
module RefinedFile
refine File do
def atime
"this one does not"
end
end
end
class C
using RefinedFile
File.new('temp').atime
end
#=> "this one does not"我们可以确认File#atime没有在类C之外被更改。
File.new('temp').atime
#=> 2019-07-16 20:20:51 -0700https://stackoverflow.com/questions/57225826
复制相似问题