fparseln(3)もどき #2
id:ha-tan:20050727のなかださんのコメントを見て、クラスIOはEnumerableをインクルードしているとはじめて知りました(ソースは以下)。
io.c ... 5311 void 5312 Init_IO() 5313 { ... 5353 rb_cIO = rb_define_class("IO", rb_cObject); 5354 rb_include_module(rb_cIO, rb_mEnumerable); ...
ということで、なかださんのコメントを反映した版を以下に貼っておきます。
module Enumerable def parseln(lineno = nil, delim = '\\\\#') esc = Regexp.escape(delim[0].chr) con = Regexp.escape(delim[1].chr) com = Regexp.escape(delim[2].chr) escre = /#{esc}(.)/ conre = /(^|[^#{esc}])#{con}$/ comre = /(^|[^#{esc}])#{com}/ buf = '' self.each do |line| line.chomp! lineno += 1 unless lineno.nil? if line =~ comre line = $` + $1 next if line.size == 0 and buf.size == 0 end if line =~ conre buf += ($` + $1).gsub(escre, '\1') next end buf += line.gsub(escre, '\1') if lineno.nil? yield(buf) else yield(buf, lineno) end buf = '' end end end
IOのメソッドにするよりもEnumerableのメソッドにした方が汎用でよいのですが、このメソッド本来の用途がぼけてしまいそうですね…