我可以从Ruby中的必需脚本访问DATA吗?

时间:2010-01-28 17:47:55

标签: ruby

是否可以在“主”脚本以外的ruby文件中访问__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”?

2 个答案:

答案 0 :(得分:6)

不幸的是,加载“main”脚本时会设置DATA全局常量。一些可能会有所帮助的事情:

可以至少让A_DATA正确无误。只需颠倒a.rb中前两个操作的顺序:

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

如果你经历了一些严峻的考验,你可以让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__)

答案 1 :(得分:4)

实施@ James建议使用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