latest log

酩酊状態で書いたエンジニアポエムです。酩酊状態で読んでください。

mm.allow によるアサーションとステキログ

mofmof.js には mm.allow() や mm.deny() といった assertion(アサーション, 前提条件のチェック) のための関数があります。

mm.allow は関数の入り口で多用され、引数の型や内容が正しいか確認し、まずい場合は例外を挙げます。
mm.deny は mm.allow の逆の動作をします。

mm.allow の使用例

mm.has は集合(data)が要素(find)を含んでいると true を返します。
data と find には複数の型を指定できますが data に文字列を指定すると例外が発生します。

// mm.has
function mm_has(data,   // @arg Hash/Function/Array:
                find) { // @arg Hash/Function/Array/Primitive: find values, { key: value }
                        // @ret Boolean:
                        // @help: mm#mm.has
                        // @desc: has value(s), has hash pair(s)
//{@assert
    mm.allow(data, "Hash/Function/Array");
    mm.allow(find, "Hash/Function/Array/Primitive");
//}@assert

    switch (mm_type(data)) {
    case "function":
    case "object":  return _ObjectHas(data, find); // Object#has(hash)
    case "array":   return data.has(find); // Array#has
    }
    return mm_values(data).has(find); // Array#has
}

アサーション時に生成されるステキログ

ここで試しに、 mm.has("weeee") とコンソールに入力してみます。
すると、mm.allow 内部にある debugger; でカーソルが一次停止します。

f:id:uupaa:20120705055327p:plain

コールスタックで問題発生箇所と、周囲の環境(変数)を確認できる

この状態で画面右にある call stack を遡ってゆくと、どこでどのような理由で assert が発生しようとしているのか、その時々の変数の状態がどうなっているのかを把握する事ができます*1

f:id:uupaa:20120705055236p:plain

そのまま実行を続けると、コンソールにスタックトレースが表示されます。

f:id:uupaa:20120705055411p:plain

よく見ると mm_has 関数内の mm.allow("weeee", "Hash/Function/Array") で本来指定できない値("weeee")が指定されたため assert が発生したことが分かります。

また、see: http://code.google.com/p/mofmof-js/wiki/mm#mm.has の行はクリック可能になっており、クリックすると mm.has のヘルプページが新しいタブで開きます。

関数の実装をチラ見したい場合は

(ε・◇・)з ヘルプページわざわざ表示するのめんどいから、もっと手軽に引数とか戻り値を確認したいなー

コンソールに mm.has と入力してください。

mm.has のソースコードが引数や戻り値の情報付きでダンプされます。

f:id:uupaa:20120705062149p:plain

mm.allow や mm.deny はリリース版のソースコードからは削除されます

//{@assert
mm.allow(...)
//}@assert

となっていると、minify時に自動的にソースコードから削除されるため、安心して利用できます。

mofmof.js には、ボクがこれまでの開発で必要だと思ったステキ機能を満載しています

mofmof.js には

  • ビルド時のコード最適化と、不要なコードの除去機能
  • mm.allow や mm.deny などのアサーション機能
  • mm.dump や Array#dump によるオブジェクトダンプ, uu.dump によるノードツリーダンプ
    • mm.say(object) で素早くオブジェクトダンプ
  • mm("MyClass", ...) でクラスの定義
  • mm.msg による、クラスインスタンス間のメッセージング。クラス間の疎結合を実現
  • コンソールで mm.has.help() のように、関数名.help() と打つと関数の実体とヘルプページへのリンクを表示
  • mm.log で コンソール, サーバのアクセスログ, alert に同時/選択的出力
  • ES5 のほぼ全てと ES.next の機能の幾つかが利用可能
  • Future, Stream, UnitTest
  • JavaDocメントスタイルは非効率なので廃止、オンラインコメントスタイルで記述

といった、開発者を支援するための機能をコツコツと実装してたりします。

mofmof.js と mofmof.js の上に組まれた新しい uupaa.js を使ったアレを開発中なので、そのうちまとめて紹介できるといいなー って感じです。


遊び心++

mofmof.js に o_o とあったら、それは予定された(意図した)例外処理です

try {
  ...
} catch (o_o) { // ふーん
  ...
}

o_O や O_o があったら、それは予定外の例外処理です。

try {
  ...
} catch (o_O) { // おぇぇ?
  ...
}

(ε・◇・)з ふーん

*1:開発中は、特にこの機能が活躍します