我正在编写一个应用程序,我希望与1.9.3版本的Ruby版本保持兼容,并且应该在MRI Ruby和JRuby下运行。到目前为止,这不是真正的问题,直到我决定使用标准库中的Delegator
类。虽然我在编写代码时使用了1.9.3 Ruby版本的文档,但我的程序使用的是Ruby 2.3或JRuby 9.x,但不适用于JRuby 1.7(它对应于Ruby 1.9.3代码库。现在我可以通过将此归因于较旧的Ruby代码中的错误,可以轻松地将其处理掉;但是,行为的详细信息是我无法理解简单错误如何解释这一点。也许我正在使用Delegator类以错误的方式,它只是发生在新的Ruby版本中偶然工作。这是一个相当小的例子,显示了行为:
require 'delegate'
class DelegFile < Delegator
def initialize(filename)
@fp = File.new(filename, "w:UTF-8", {universal_newline: true})
super(@fp)
end
def out_1
self.puts('yyyy1111')
end
def out_2
puts('yyyy2222') # This causes trouble
end
def __getobj__
@fp
end
def __setobj__(obj)
@fp = obj
end
end
# Using the class
df = DelegFile.new("x.bak")
df.puts('xxxx')
df.out_1
df.out_2 # Writes to STDOUT!
df.puts('yyyy')
df.close
类DelegFile的对象基本上表现得像File,添加了两个方法和一个专门定制的构造函数。当然,人们可以在这里同样好,例如,使用File的继承,但我想在使用Delegator
时证明问题:
当我在新的Ruby / JRuby版本上运行此程序时,所有 puts 语句都将其输出写入文件。在旧的Ruby版本(1.9.3,...)上运行时,字符串 yyyy2222 将写入STDOUT,而其他所有内容都会在文件中结束。
换句话说,
puts
我的班级里面的不委托,而是调用Kernel#puts
,而
self.puts
代表。
我原以为,方法调用foo()
等同于self.foo()
,除非 foo 是私有方法。现在,为什么我可能会在puts
和self.puts
之间看到不同的行为?