2013-08-29 1 views
3

루비에서는이 DATA IO 객체를 통해 임의의 사용 __END__ 후 정적 텍스트를 저장하기 위해 정말 편리합니다 :클래스 컨텍스트에서 DATA를 참조 할 수없는 이유는 무엇입니까?

puts DATA.read # Prints "This is the stuff!" 
__END__ 
This is the stuff! 

그러나, 나는 예기치 않은 오류를 얻을 새로운 클래스의 맥락에서 데이터 객체를 참조 할 때 (Ruby 1.9.3과 2.0에서는 분명히) :

class Foo 
    STUFF = DATA.read # <class:Foo>: uninitialized constant Foo::DATA (NameError) 
end 

class Foo 
    STUFF = ::DATA.read # <class:Foo>: uninitialized constant DATA (NameError) 
end 

내가 어떻게이 작업을 할 수 있었는지 생각해보십시오.

+0

페이지의 File.read(__FILE__).split("\n__END__\n", 2)[1]를 사용하는 경향이 : [HEREDOCS] (http://blog.jayfields.com/2006/12/ruby-multiline-strings-here-doc-or. html). – Ajedi32

+0

@ Ajedi32 : 네, heredoc을 고려했으나 실제 사용 사례는 후행 데이터로 가장 잘 작동 할 대형 ERB 템플릿을 저장하고 있습니다.heredoc을 사용하여 클래스 정의 범위 내에 맞춰야하지만 어쩌면 별도의 파일에서 읽지 않으려 고하는 댓가로 지불해야 할 수도 있습니다. – maerics

+1

'STUFF = DATA.read'에서 오류를 확인할 수 없습니다 : [snippet] (http://ideone.com/6dbCoE). – steenslag

답변

7

이미이 코멘트, 즉 오류가 없습니다 확인, Babai 또한 작업 예제를 게시했습니다.

은 어쩌면 당신은 또 다른 문제가 있습니다

DATA는 주요 문서가 아닌 실제 소스 코드 파일의 __END__ 후 텍스트에 해당합니다.

그것은 작동 :

여기
class Foo 
    STUFF = DATA 
    p STUFF.read 
end 
__END__ 
This is the stuff! 

소스 코드 파일과 주요 파일이 동일합니다. 당신이 test_code.rb로 저장하고 주요 파일을로드하는 경우

는하지만 : 주요 파일을 다시

require_relative 'test_code.rb' 

__END__ 
This is the stuff! 
경우

C:/Temp/test_code.rb:2:in `<class:Foo>': uninitialized constant Foo::DATA (NameError) 
    from C:/Temp/test_code.rb:1:in `<top (required)>' 
    from test.rb:1:in `require_relative' 
    from test.rb:1:in `<main>' 

:

require_relative 'test_code.rb' 

그런 다음 당신은 오류

그러면 출력은 과 함께 작동합니다. 당신은 주 파일의 한 부분으로, 도서관에서 __END__을 사용할 수 없습니다

  • :

    은 귀하의 질문에 대답합니다.

  • 대신 여기에 문서를 사용하거나 데이터를 외부 데이터 파일에 저장하십시오.
+0

"라이브러리에서'__END__ '을 (를) 주 파일의 일부로 만 사용할 수 없습니다." <-이게 설명해, 나는 루비가 아니라 irb를 사용했다. 바보 같은 ... =) – maerics

+2

@maerics 라이브러리에서'__END__ '을 사용할 수 있습니다. 사용할 수없는 것은'DATA'뿐입니다. 직접 파일을 열면됩니다. '__FILE__' 또는''Kernel :: caller' (http://ruby-doc.org/core-2.0.0/Kernel.html#method-i-caller)를 사용하여 파일 이름을 얻으십시오. Sinatra가 인라인 템플릿으로 사용하는 템플릿을 예로 들어 보겠습니다. https://github.com/sinatra/sinatra/blob/v1.4.3/lib/sinatra/base.rb#L1254-1283. – matt

+0

@matt : 링크를 제공해 주셔서 감사합니다. 매우 도움이됩니다. – maerics

0

좋은 블로그가 여기에 있습니다 : - Useless Ruby Tricks: DATA and END

이 작동하는 방법이다 :

class Foo 
    def dis 
    DATA.read 
    end 
end 
Foo.new.dis # => "This is the stuff!\n" 
__END__ 
This is the stuff! 

class Foo 
    STUFF = DATA 
    p STUFF.read 
end 
__END__ 
This is the stuff! 
# >> "This is the stuff!\n" 

RUBY_VERSION # => "2.0.0" 
class Foo 
    p STUFF = DATA.read 
end 
__END__ 
This is the stuff! 
# >> "This is the stuff!\n" 
+0

@maerics see now ... :) –

관련 문제