2015-07-05 4 views
5

Kürzlich habe ich Ruby gelernt. Ich habe ein Problem, während ich eine Unterklasse von Datei schreibe.Ruby IO - Datei Eingabe/Ausgabe indirekt

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 

Ergebnis:

line 1 
line 2 
line 3 

Wenn ich ausgegeben werden soll durch den Aufruf einer Methode:

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 

Ergebnis:

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

Dann füge ich neue Methode 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 

Ergebnis:

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

Also, ich bin so verwirrt über IO in Ruby.Why puts line in foo kann auch nicht funktionieren.

Antwort

6

Es gibt eine puts method in IO und IO ist eine Oberklasse von File. Das bedeutet, dass diese:

puts line 

tatsächlich self.puts ist eher als Kernel#puts wie es so ziemlich überall sonst ist, dass man puts verwenden. Daher die Fehlermeldung "nicht zum Schreiben geöffnet".

Sie benötigen einen expliziten Empfänger, um den gleichen Effekt wie Kernel#puts zu erhalten; Kernel#puts entspricht $stdout.puts so Sie wollen:

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

Ihre p line Version funktioniert gut, weil es keine IO#p oder File#p Methode ist, p ist Kernel#p so wie es überall ist.

Denken Sie daran, dass wir in Ruby keine Funktionen haben, wie andere Sprachen globale Funktionen haben. Methoden, die Sie wie eine Funktion verwenden, sind fast immer Methoden in Kernel.

0

Sie können auch $> "den Standard-Ausgangsstrom" verwenden, um die Ausgabe von Methoden wie Kernel # puts umzuleiten ... Was ist die einzige Aufgabe von $>.

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

Ich fügte hinzu, ein weiteres Verfahren zeigt, wie Sie auch „require“ andere Edelsteine ​​ausleihen können (zB ziemlich druckten Juwel) und die Verwendung von class << slef .... also, Sie haben gesagt „Vor kurzem habe ich gelernt Rubin ": |

Das Folgende funktioniert wie vorgesehen.

#!/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 

Hinweis: Die Verwendung von NameOfClass < < selbst ...Wana mehr lesen SO question

Was scheint btter:

nicht-recht-gedruckte Ausgabe von 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>> 

pretty-gedruckte Ausgabe von 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> 

Weitere über pp gehen hier Ruby-Doc