2008年 07月 20日

ゆの in Ruby エラーメッセージ

クソ長いです

#!/usr/bin/env ruby -Ku
# vim:set ft=ruby:
# ひだまりスケッチ× というファイル名で保存する必要があります
X = 365


















































































































































































































































































































































t = Time.now
t += 7 * 24 * 60 until t.wday == 4
n = t.strftime("X365次は%m月%d日25時25分からです><")
eval "class #{n} < Exception; end"



alias _ raise
$! = Kernel.const_get(n).new(File.read(__FILE__)[/< (.+!)$/, 1])













X / _ / X < 来週も見てくださいね!

出力はこんな風になります。

ひだまりスケッチ×:365: 来週も見てくださいね! (X365次は07月24日25時25分からです><)

方針としては

  • 365行目で raise させる

ってだけです。

Ruby のエラーメッセージはトップレベルの場合

filename:line: message (ErrroClassName)

になります。トップレベルではない場合は in`methodname` が入ってくるのでダメです。そこで _ を raise の alias にすることで、raise と書かなくても例外をゆのっち内で起こせるようにしました。_ には引数がないので、引数なしの raise となり、直前の例外が raise される効果になります。「直前の例外」は $! に入っており、代入することもできるので、例外を生成して直接 $! へ代入しています。

$! へ代入するクラスの名前が、エラーメッセージの括弧内に入るので、オマケで次週の TBS での放送日を入れることにしました。const_name として valid な名前にするのが結構めんどいうえに綺麗にならないですがこんなもんでしょうか。

短かいバージョン ファイル名も行数も関係なし。上のコードは _ でプログラムを抜けて「来週も見てくださいね!」が評価されないのですが、これだとされます。

#!/usr/bin/env ruby -Ku
# vim:set ft=ruby:

class X < (_ = Exception)
	class << self
		def /(o)
			self
		end

		def <(o)
			raise X, o.to_s
		rescue Exception
			$!.set_backtrace(["ひだまりスケッチ×365"])
			raise
		end
	end

end

class Object
	def method_missing(name, *args)
		name
	end
end

X / _ / X < 来週も見てくださいね!
ひだまりスケッチ×365: 来週も見てくださいね! (X)