Ruby IO - 间接文件输入/输出

Vei*_*hou 5 ruby file

最近我一直在学习Ruby.我在编写File的子类时遇到了问题.

class MyFile < File

end

file_path = "text_file"

file = MyFile.open(file_path) do | file |
    file.each_line do | line |
        puts line
    end
    file.close
end
Run Code Online (Sandbox Code Playgroud)

结果:

line 1
line 2
line 3
Run Code Online (Sandbox Code Playgroud)

如果我想通过调用方法来输出:

class MyFile < File
    def foo
        self.each_line do | line |
            puts line
        end
    end
end

file_path = "text_file"

my_file = MyFile.open(file_path) do | file |
    file.foo
    file.close
end
Run Code Online (Sandbox Code Playgroud)

结果:

/Users/veightz/Developer/RubyCode/io_error.rb:4:in `write': not opened for writing (IOError)
    from /Users/veightz/Developer/RubyCode/io_error.rb:4:in `puts'
    from /Users/veightz/Developer/RubyCode/io_error.rb:4:in `block in foo'
    from /Users/veightz/Developer/RubyCode/io_error.rb:3:in `each_line'
    from /Users/veightz/Developer/RubyCode/io_error.rb:3:in `foo'
    from /Users/veightz/Developer/RubyCode/io_error.rb:20:in `block in <main>'
    from /Users/veightz/Developer/RubyCode/io_error.rb:19:in `open'
    from /Users/veightz/Developer/RubyCode/io_error.rb:19:in `<main>'
Run Code Online (Sandbox Code Playgroud)

然后我添加新方法 bar

class MyFile < File
    def foo
        self.each_line do | line |
            puts line
        end
    end

    def bar
        self.each_line do | line |
            p line
        end
    end
end

my_file = MyFile.open(file_path) do | file |
    file.bar
    file.close
end
Run Code Online (Sandbox Code Playgroud)

结果:

"line 1\n"
"line 2\n"
"line 3\n"
Run Code Online (Sandbox Code Playgroud)

所以,我对Ruby puts line中的IO很困惑.为什么foo不能正常工作.

mu *_*ort 6

有一个puts方法,IO并且IO是一个超类File.这意味着:

puts line
Run Code Online (Sandbox Code Playgroud)

实际上,self.puts而不是Kernel#puts在你使用的其他任何地方puts.因此,"未打开写入"错误消息.

你需要一个明确的接收器来获得相同的效果Kernel#puts; Kernel#puts相当于$stdout.puts你想要的:

file.each_line do | line |
  $stdout.puts line
end
Run Code Online (Sandbox Code Playgroud)

p line因为没有版本能正常工作IO#pFile#p方法,pKernel#p就像它是在其他地方.

请记住,我们在Ruby中没有其他语言具有全局功能的方式.像函数一样使用的方法几乎总是方法Kernel.