仅为一个实例重新定义SomeClass#

时间:2016-03-01 09:40:22

标签: ruby

我有一个方法f(x),其中对参数x的唯一要求是它实现了each方法,而每次迭代都产生一个字符串。

我可以通过

使用f来生成文件的行
myfile = File.open('....')
f(myfile)
myfile.close

现在出现了扭曲:File#each返回文件的每一行,包括换行符,但我希望f使用文件的chomped行。我不想触及f的实现。

一个解决方案可能(我不确定这个解决方案对于each的使用是否合理)是否为File的子类:

class ChompingFile < File
  alias_method :file_each,:each
  def each
    file_each {|line| yield(line.chomp)}
  end
end

myfile = ChompingFile.open('....')
f(myfile)
myfile.close

但是,如果没有子类化,我可以做同样的事情,但修改实例myfile吗?我的第一次尝试是

myfile = File.open(.....)
myfile.alias_method(:file_each,:each) # DOES NOT WORK
def myfile.each
    file_each {|line| yield(line.chomp)}
end
f(myfile)
myfile.close

这会产生错误,alias_method未定义。我想我只有在self绑定到一个类而不是一个实例时才能使用它。

有可能实现我想要的吗? (而且,这样做是明智的吗?)

2 个答案:

答案 0 :(得分:3)

这应该

myfile = File.open(.....)

class << myfile
    alias_method :file_each, :each

    def each
        file_each {|line| yield(line.chomp)}
    end
end

答案 1 :(得分:2)

您可以拨打电话super :(由JörgWMittag作为suggested

def myfile.each
  super { |line| yield(line.chomp) }
end

示例:

require 'stringio'
myfile = StringIO.new("foo\nbar\nbaz\n")

myfile.each { |line| p line }
#=> "foo\n"
#   "bar\n"
#   "baz\n"

def myfile.each
  super { |line| yield(line.chomp) }
end

myfile.rewind
myfile.each { |line| p line }
#=> "foo"
#   "bar"
#   "baz"
相关问题