おまぬけ活動日誌

最近のツッコまれどころ

この日誌から Google してもらう


2012年10月12日(Fri) 久しぶりに歩いたよ [同日]

[tDiary][Ruby] プラグインをテストするフレームワークがつくれない

テストケースの中でプラグインに書くのと同じコードが書けるとうれしいと思って ヘルパを用意しようとしているのだけれど、 プラグインのコードの中で定義されたクラスにアクセスできない。

どうも、下記が最小限のコードに近いような気がする。 フレームワーク中でプラグインのコードをinstance_eval()するメソッドを定義して テストケース中からロードし実行するのを模して、 モジュールM内でクラスXの定義をinstance_eval()するメソッドmを定義して トップレベルから実行してみる。

module M
	def m
		instance_eval('class X; end')
		return X
	end
end

include M
p m	#=> in `m': uninitialized constant M::X (NameError)

class Xをみつけられない。

モジュール内に囲いこまなければ期待通り動作してくれる。

def m
	instance_eval('class X; end')
	return X
end

p m	#=> #<Class:0x8486ab8>::X

僕はモジュールについて何か勘違いしてるんだろうな。

(追記) instance_eval()じゃなくてeval()なら ほぼ期待通りに動くんだよね。 でもテストケースにする時は、それぞれのテスト(スイート?)について 繰り返し読まれるのでinstance_eval()にしておきたい。

module M
	def m
		eval('class X; end')
		return X
	end
end

include M
p m

(また追記) evalで定数を再定義するWarningが出るコード。

module M
	def m
		eval("C='#{k}'")
		return C
	end
end

class X
	include M
	def k
		'in X'
	end
end


class Y
	include M
	def k
		'in Y'
	end
end

p X.new.m	#=> "in X"
p Y.new.m	#=> (eval):1: warning: already initialized constant C/"in Y"

(追記) kouさんによる、 コードをロードするためのクラスを毎回作る方法

あと、この日誌はvolatile.tdrが大きくなりすぎると一日分のレンダリングがタイムアウトするような気がする。


作り手とその取り巻きだけが楽しんでる間は本物じゃない。その中身が理解できない人々の生活を変えてこそ本物だ


zunda <zunda at freeshell.org>