2009-08-26 9 views
15

używam tej sztuczki Ruby z __END__ i DATA umieścić niektóre dane w moim pliku programu:Ruby zakres danych po __END__

class Foo 
    def initialize() 
    puts DATA.read.inspect 
    end 
end 
puts DATA.read.inspect 
Foo.new 
__END__ 
test 

To generuje następujący wynik:

"test" 
"" 

I założył, że DATA będzie taki sam na całym świecie, ale w klasie nie ma treści. Jak uzyskać dostęp do danych po __END__ w klasie (oprócz oczywistego i brzydkiego rozwiązania wykorzystującego zmienne globalne)?

DODANO: Widzę, że dwukrotne czytanie mnie dwukrotnie nie daje mi nic. Mogę użyć numeru rewind, aby wrócić do początku, ale read daje mi wtedy cały kod źródłowy mojego programu. Czy istnieje łatwiejszy sposób, aby uzyskać dostęp do części po __END__ w następnych użyciach DATA, czy lepiej byłoby ją przeczytać raz i przechowywać w innym miejscu do wykorzystania w przyszłości?

Odpowiedz

20

Dane są takie same. Otrzymasz te same wyniki, jeśli zamiast robić Foo.new będziesz robił DATA.czytaj po raz drugi.

To dlatego, że po raz pierwszy przeczytałem DATA (który jest IO) osiągnęła koniec strumienia, tak dalej czyta zwróci pusty ciąg, chyba że dołączania dodatkowych danych do danych lub do tyłu DATA do początku strumień.

Edit: Aby zasięgnąć powrotem na prawo punkt po __END__ trzeba czytać DATA.pos przed wykonaniem jakichkolwiek odczyt na DATA a następnie przywrócić pos do tej wartości po przeczytaniu. Najprostszym rozwiązaniem jest prawdopodobnie zrobienie FOO = DATA.read na początku skryptu, a następnie użycie FOO.

+0

Wykonanie 'FOO = DATA.read' utraci zalety przeliczalnego obiektu' IO'. "FOO = StringIO.new (DATA.read," r ")" może być lepsze? (Najpierw "wymagaj" ciągi ") – AlvaPan

-3

najpierw przewiń DANE, ponieważ jest to strumień.

class Foo 
    def initialize() 
    DATA.rewind 
    puts DATA.read.inspect 
    end 
end 
puts DATA.read.inspect 
Foo.new 
__END__ 
test 
+1

Wydaje mi się, że daje mi to całą zawartość pliku, a nie tylko część po' __END__'. – avdgaag

Powiązane problemy