RCR 213: Extended Access to the DATA Pseudo-File
submitted by austin on Wed Feb 11 2004 08:00:46 PM -0800
Status: pending
Abstract
Make it so that the DATA pseudo-file can refer to the DATA section of the file that is currently be read, not just the DATA section of $0.
Problem
In Perl, the <DATA> file refers to the current file, whereas in Ruby it refers exclusively to the DATA section in $0. This means that libraries that have related data must find other ways to either embed the data or find a separate location for it (which has its own problems on installation).
Proposal
Create a new default class, ENDData, that will provide the ENDData of any file that has been required or explicitly requested. The class itself holds a cache hash of StringIO objects representing the DATA section of the file in question. The Ruby interpreter would generate the StringIO objects automatically when it encounters an __END__ marker in any file.
Analysis
The problem here is mostly one of performance. The EndData object can be implemented purely in Ruby, but as the Ruby interpreter is already having to handle __END__ markers in source files, this would make it so that the data is available for required libraries. * A drawback to this is that it keeps the data in memory even if it is not used. This could be fixed by the 'require' method calling EndData.clear(required_file) at the end of the require execution.
Implementation
A simplistic implementation of ENDData follows:
class ENDData
class << self
def for_file(fn = $0)
return DATA if fn == $0
return @cache[fn] if (@cache ||= {})[fn]
str = File.read(fn).scan(/__END__\n(.*?)$/m).last[0] rescue nil
raise(IOError, "#{fn} doesn't have any DATA") unless str
@cache[fn] = StringIO.new(str)
end
def clear_cache(fn)
(@cache ||= {})[fn] = nil
end
end
end
Back to RCRchive.
RCR Submission page and RCRchive powered by Ruby, Apache, RuWiki (modified), and RubLog