Skip to content
uupaa edited this page Feb 25, 2016 · 19 revisions

Valid.js は Assertion 機能を提供するライブラリです。

JavaScript does not have a solid-type-system.

JavaScript には静的な型チェックシステムがなく Assertion 機能もありません。
(Assertion とは、プログラマーが「この場合はこうあるべき」と考えている内容をコードで表明したものです。プログラムの矛盾やバグをコンパイル時や実行時に検出する目的で使われます)

Valid.js は JavaScript に不足しているこれらの機能を提供します。

サポートしている型の一覧 も参照してください。

WebModule には Valid.js がデフォルトで組み込まれており、WebModule でも Valid.js の機能を利用可能です。
(WebModule 動作環境では Valid.type() ではなく $type() でアクセスします)。

リリース環境への対応

Assertion は、デバッグ中は大変有効な機能ですが、十分にデバッグが終わっている前提のリリースビルドにおいては、オーバーヘッドを生む不要な存在です。

WebModule を使うと、リリースビルドから Assertion を取り除くことができます。

to remove the assertion code from release builds.

リリースビルドから Assertion コードを取り除くには以下のようにします。

WebModule には、{@assert ... }@assert, {@debug ... }@debug, {@dev ... }@dev で囲われたコードブロックをビルド時に自動的に削除する機能(プリプロセス)があります。Valid.js でもこれを使ってコードを取り除きます。

// このコードは残ります
console.log("hello")

//{@assert
for (var i = 0; i < 10000000000; ++i) {
    console.log(i);
}
//}@assert

//{@debug
alert("debug");
//}@debug

//{@dev
alert("develop");
//}@dev

上記のコードを npm run min でビルドすると、
{@assert ... }@asset,
{@debug ... }@debug,
{@dev ... }@dev,
部分は全て消えます。

// このコードは残ります
console.log("hello")

使い方

lib/Valid.js や lib/WebModule.js には以下の validate / assertions コードが埋め込まれています。

...

// --- validate and assert functions -----------------------
//{@dev https://github.com/uupaa/WebModule/wiki/Validate
GLOBAL.$type  = function(v, types)   { return GLOBAL.Valid ? GLOBAL.Valid.type(v, types)  : true; };
GLOBAL.$keys  = function(o, keys)    { return GLOBAL.Valid ? GLOBAL.Valid.keys(o, keys)   : true; };
GLOBAL.$some  = function(v, cd, ig)  { return GLOBAL.Valid ? GLOBAL.Valid.some(v, cd, ig) : true; };
GLOBAL.$args  = function(api, args)  { return GLOBAL.Valid ? GLOBAL.Valid.args(api, args) : true; };
GLOBAL.$valid = function(v, api, hl) { return GLOBAL.Valid ? GLOBAL.Valid(v, api, hl)     : true; };
GLOBAL.$values = function(o, vals)   { return GLOBAL.Valid ? GLOBAL.Valid.values(o, vals) : true; };
//}@dev

...

$valid, $type$keys{@dev ... }@dev コードブロックに埋め込んで利用します。

function foo(value) { // @arg Boolean = false

//{@dev
    $valid($type(value, "Boolean|omit"), foo, "value");
//}@dev

}

使用例

以下の foo は引数(param, callback) をチェックせず、別の関数 bar にそのまま渡しています。
foo は渡された引数に問題があるかどうかをチェックしていないため、 より深い部分(bar)でエラーが発生した場合に、 原因の特定に手間がかかるコードになっています。

// ナイーブなコード
function foo(param,      // @arg Object - { type, target }
                         // @param.type String - "DOM" or "SVG" or "CSS"
                         // @param.target String = ""
             callback) { // @arg Function = null - callback(param.type:String, param.target:String = ""):void
    bar(param, callback);
}

function bar(param, callback) {
    if (callback) {
        callback(param.type, param.target);
    }
}

このようなコードはナイーブ(脆弱)なコードと呼ばれます。
ナイーブなコードをより頑強でソリッドなコードにするのが Valid.js です。

以下のようにすることで、型のチェックや、keys/values のバリデーションが行えます。

// ソリッドなコード
function foo(param,      // @arg Object - { type, target }
                         // @param.type String - "DOM" or "SVG" or "CSS"
                         // @param.target String = ""
             callback) { // @arg Function = null - callback(param.type:String, param.target:String = ""):void
//{@dev
    // [1] param が Object型 な事を確認しています
    // [2] Object.keys(param) に含まれる key が "type" と "target" で、それ以外の不純物がない事を確認しています
    // [3] param.type が String型 な事を確認しています
    // [4] param.type の内容が "DOM", "SVG", "CSS" の何れかである事を確認しています
    // [5] param.target が String型 で省略可能な事を確認しています
    // [6] callback が Function型で省略可能な事を確認しています

    $valid($type(param, "Object"),             foo, "param");        // [1]
    $valid($keys(param, "type|target"),        foo, "param");        // [2]
    $valid($type(param.type, "String"),        foo, "param.type");   // [3]
    $valid($values(param.type, "DOM|SVG|CSS"), foo, "param.type");   // [4]
    $valid($type(param.target, "String|omit"), foo, "param.target"); // [5]
    $valid($type(callback, "Function|omit"),   foo, "callback");     // [6]
//}@dev

    bar(param, callback);
}

function bar(param, callback) {
    if (callback) {
        callback(param.type, param.target);
    }
}
foo({ type: "Canvas", target: "..." }, function(type, target) { });

上記の誤った( type: "Canvas" )のコードを指定すると、Valid.js が機能する様子を確認することができます。
Assertion が発動すると、DevTools のコンソールに foo の内容がダンプされ、 問題の箇所( param.type )がハイライト表示されます。