最近かったクリムゾン

FAMILIAR COMPUTING WORLD

FAMILIAR COMPUTING WORLD

21世紀アホの子のカバーが面白かったので買った。
King Crimson Songbook 1

King Crimson Songbook 1

某所で聞いたと思ったら買っていた。
これはやばいばい!

http://www.nicovideo.jp/watch/sm574267
http://www.nicovideo.jp/watch/sm1212870

引数のデフォルト値を簡単に

iolanguageを初めてみた。
可変長引数やデフォルト値付きのメソッドを作りたい時
普通だと

faito := method(
	msg := call message
	if(msg argCount < 1, "ねこ", call sender doMessage(msg argAt(0))) print
	"が" print
	if(msg argCount < 2, "なぐる", call sender doMessage(msg argAt(1))) println
)
faito
faito("いぬ")
faito("いぬ", "ける")

こんな感じで非常に面倒になるはず

そこでおもむろにメソッドを定義

Object def := method(narg,
	msg := call sender call 
	if (msg argCount > narg, 
		call sender call sender doMessage(msg argAt(narg)),
		if (call argCount >= 2, call sender doMessage(call argAt(1)), nil)
	)
)

どのコンテキスト(?)で評価されるのかに注意。
call sender で呼び出し側までさかのぼる。

使い方

fight := method( 
	def (0, "ねこ") print
	"が" print
	def (1, "なぐる") println
)
dog := "いぬ"
kick := "ける"
fight
fight(dog)
fight(dog, kick)

出力

ねこがなぐる
いぬがなぐる
いぬがける     

デフォルト値は、引数が指定されたときは評価されない仕様

引数の有無で挙動を変える

プロパティ的なもの作りたくて考えてみた。

	neko tails #=> 1 が返る
	neko tails(2) #=> 2 を設定
	neko tails #=> 2 になってる

call sender で呼び出し元のオブジェクトを得て、call argAt(0) name で引数の名前が得られる模様。
なので、

Object argif := method(narg,
	msg := call sender call 
	if (msg argCount > narg, 
		call sender setSlot(call argAt(1) name, call sender call sender doMessage(msg argAt(narg)))
		def(2),
		def(3)
	)
)


Neko := Object clone
Neko init := method(
	self _tails := 1
)
Neko tails := method(
	argif(0, n, self _tails := n, self _tails)
)
neko := Neko clone
neko tails println
neko tails(2) println
neko tails println

これでOK?