2010-01-28 11 views
9

क्या "मुख्य" स्क्रिप्ट के अलावा एक रूबी फ़ाइल में __END__ के बाद टेक्स्ट तक पहुंच बनाना संभव है?क्या मैं रूबी में एक आवश्यक स्क्रिप्ट से डेटा तक पहुंच सकता हूं?

उदाहरण के लिए:

# b.rb 
B_DATA = DATA.read 
__END__ 
bbb 

# a.rb 
require 'b' 
A_DATA = DATA.read 
puts 'A_DATA: ' + A_DATA 
puts 'B_DATA: ' + B_DATA 
__END__ 
aaa 

C:\Temp>ruby a.rb 
A_DATA: 
B_DATA: aaa 

वहाँ किसी भी तरह से b.rb से "bbb" में प्राप्त करने के लिए है?

उत्तर

6

दुर्भाग्यवश, DATA वैश्विक स्थिरता तब सेट की जाती है जब "मुख्य" स्क्रिप्ट लोड हो जाती है। कुछ चीजें जो मदद कर सकती हैं:

कम से कम A_DATA सही होने के लिए प्राप्त कर सकते हैं। बस a.rb में पहले दो आपरेशन के क्रम को उल्टा:

# a.rb 
A_DATA = DATA.read 
require 'b' 
... 

आप प्राप्त कर सकते हैं अगर आप rigamarole का एक सा के माध्यम से जाने B_DATA सही होने के लिए:

# load_data_regardless_of_main_script.rb 
module LoadDataRegardlessOfMainScript 
    def self.from(file) 
    # the performance of this function could be 
    # greatly improved by using a StringIO buffer 
    # and only appending to it after seeing __END__. 
    File.read(file).sub(/\A.*\n__END__\n/m, '') 
    end 
end 

# b.rb: 
require 'load_data_regardless_of_main_script' 
B_DATA = LoadDataRegardlessOfMainScript.from(__FILE__) 
+0

यह अभिव्यक्ति __END__: s = ~/^ __ END __ \ n/&& $ ' –

+0

' फ़ाइल.read (__ फ़ाइल __) के बाद सामान प्राप्त करने के लिए भी काम करती है ... 'फ़ाइल.read (फ़ाइल) होना चाहिए ... 'से 'विधि में। –

+0

अच्छी पकड़, ग्लेन। –

4

को लागू @ जेम्स के सुझाव StringIO उपयोग करने के लिए :

require 'stringio' 
module LoadDataRegardlessOfMainScript 
    def self.from(filename) 
    data = StringIO.new 
    File.open(filename) do |f| 
     begin 
     line = f.gets 
     end until line.match(/^__END__$/) 
     while line = f.gets 
     data << line 
     end 
    end 
    data.rewind 
    data 
    end 
end 

फिर b.rb हो जाता है

require 'load_data_regardless_of_main_script' 
B_DATA = LoadDataRegardlessOfMainScript.from(__FILE__).read 
+0

+1 से कम आलसी होने के लिए +1 :) –

+0

एक महान उदाहरण के लिए – RyanScottLewis

+0

+1 के लिए +1 की तरह अधिक पसंद है! मैंने जो बदलाव किया है वह 'लाइन तक नहीं है। या line.match (/^__ अंत __ $ /) '। इस तरह विधि को बिना किसी जानकारी के किसी भी रूबी फ़ाइल के खिलाफ चलाया जा सकता है यदि उसके पास 'डेटा' अनुभाग है। – Sharpie

संबंधित मुद्दे