NULL::something

Login via flickr, はてな, TypeKey.

2004-12-07

iolanguage メソッドの引数の評価

素朴な疑問にひっかかった。if とか else もメソッドで、引数にメッセージをとるけど、何でこの引数は評価されずに渡されるんだろう。ちょっと解りにくいから実際にコードを書いてみる。

if (Nil) then (
    "not print" print
) else (
    "print" print
)

この場合もちろん not print は出力されないし、それが願う動作。しかしながら "not print" print も引数だから、メソッドに渡される前に評価されて not print と出力されるんじゃないかと悩んだ。というか正確に言えば if をユーザから定義するときに評価されてしまってハマった。以下にハマったコードを示す

myif := method(test,
    ifObj := Object clone
    ifObj test := test
    ifObj do (
        mythen := method(msg,
            if (test, sender doMessage(thisMessage argAt(0)))
            self
        )

        myelse := method(msg,
            if (test isNil, sender doMessage(thisMessage argAt(0)))
            self
        )
    )
)

myif (Nil) mythen (
    "nil" print
) myelse (
    "aaa" print
)

これは予想に反して nilnilaaa と出力される。引数が渡される前に評価されしまっているからだ。リファレンス見ててもよくわからないので、適当に書き直していたらできた。書き直した結果を書いてみる。

myif := method(test,
    ifObj := Object clone
    ifObj test := test
    ifObj do (
        mythen := method(
            if (test, sender doMessage(thisMessage argAt(0)))
            self
        )

        myelse := method(
            if (test isNil, sender doMessage(thisMessage argAt(0)))
            self
        )
    )
)

何が変わったかっていうと method の仮引数を書かないようにしただけ。仮引数を書くと評価されてしまうらしい。微妙な罠。プログラミングガイドに明記してもいいじゃん! とはいえこれを踏まえてから読み直すと The thisMessage slot that is preset (see next section) in locals can be used to access the unevaluated argument messages. と書かれていて*1 (強調はされていない) 頭がよければ thisMessage スロットには未評価なメッセージが入っていて、仮引数を書かなくても呼び出せる。もしかして仮引数を書かなければメッセージは評価されないんじゃないか、なんて推論できる (苦しい) かもしれないけど、俺には無理!

参照リソース

  1. Io Programming Guide

Comments (0)

Trackback URI: http://lowreal.net/logs/2004/12/07/4.trackback

NULL

RSS feed meter for http://lowreal.net/logs/latest

Alternates

  1. RSS 1.0
  2. Atom 1.0

Generated with Taglibro

この日記は Taglibro と呼ばれる XML ベースの XSLT をテンプレートとして使ったシステムを使っています。現在の Taglibro は Ruby, ruby-xslt, libxml-ruby による実装です。ソースコードはとりあえず公開していません。