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

5

最近我一直在学习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

结果:

line 1
line 2
line 3

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

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

结果:

/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>'

然后我添加了新的方法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

结果:

"line 1\n"
"line 2\n"
"line 3\n"

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

2个回答

6

IO中有一个puts方法,而IOFile的父类。这意味着以下内容:

puts line

实际上使用 self.puts 而不是在其他大多数使用 puts 的地方使用的 Kernel#puts。因此会出现“未打开写入”错误消息。

你需要一个显式的接收器来获得与 Kernel#puts 相同的效果;Kernel#puts 等同于 $stdout.puts,所以你需要:

file.each_line do | line |
  $stdout.puts line
end

您的p line版本很好,因为没有IO#pFile#p方法,p就像在其他地方一样,是Kernel#p

请记住,在Ruby中我们没有像其他语言中全局函数那样的函数。您几乎总是使用像函数一样的方法,这些方法通常在Kernel中。


0

你也可以使用$> "默认输出流"来重定向诸如Kernel#puts等方法的输出... 这是$> 的唯一工作。

def foo
     self.each_line do | line |
     $>.puts line
     end
end

我添加了一种方法,展示了如何借用“require”其他宝石(例如漂亮打印的宝石)以及使用class << slef。因此,你说:“最近我一直在学习Ruby”:|

以下内容按预期工作。

#!/usr/bin/env ruby

require 'pp'

class MyFile < File
class << self

    def foo
        each_line do | line |
           $>.puts line
        end
    end



    def bar
        each_line do | line |
            p line
        end
    end


    def bam
     each_line do | line |
            pp line
        end
    end

end

file_path = "/Users/path/ofdirectory_to/somefile.txt"

my_file = MyFile.open(file_path) do | file |

    file.bam
    file.foo
    file.bar
    File.close
end

注意:使用NameOfClass << self …想要了解更多SO问题 哪个似乎更好: p的非漂亮打印输出为:
  #<PP:0x81fedf0 @genspace=#<Proc:0x81feda0>, @group_queue=#<PrettyPrint::GroupQueue:0x81fed3c @queue=[[#<PrettyPrint::Group:0x81fed78 @breakables=[], @depth=0, @break=false>], []]>, @buffer=[], @newline="\n", @group_stack=[#<PrettyPrint::Group:0x81fed78 @breakables=[], @depth=0, @break=false>], @buffer_width=0, @indent=0, @maxwidth=79, @output_width=2, @output=#<IO:0x8114ee4>>

pp 生成的漂亮输出为:

 #<PP:0x81fedf0
 @buffer=[],
 @buffer_width=0,
 @genspace=#<Proc:0x81feda0>,
 @group_queue=
  #<PrettyPrint::GroupQueue:0x81fed3c
   @queue=
    [[#<PrettyPrint::Group:0x81fed78 @break=false, @breakables=[], @depth=0>],
     []]>,
 @group_stack=
  [#<PrettyPrint::Group:0x81fed78 @break=false, @breakables=[], @depth=0>],
 @indent=0,
 @maxwidth=79,
 @newline="\n",
 @output=#<IO:0x8114ee4>,
 @output_width=2>

想了解更多关于pp的内容,请访问Ruby-Doc


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接