Skip to content

Instantly share code, notes, and snippets.

@neetsdkasu
Last active September 14, 2016 10:43
Show Gist options
  • Save neetsdkasu/5837349987c4ba9fcba7e44108411baf to your computer and use it in GitHub Desktop.
Save neetsdkasu/5837349987c4ba9fcba7e44108411baf to your computer and use it in GitHub Desktop.
[JavaScript] 関数の引数をパース(?)する?(すごくショボくて使えないじょ) (この引数パースを使ってみたやつ→ https://git.io/vi20U
// parse arguments
// author : Leonardone @ NEETSDKASU
// license: MIT
// 他の関数の引数を仕分ける
////////////////////////////////////////////////////////////////////////////////
// parseArguments(args, xpnd)
// args ... 仕分け対象の関数の引数 (自動変数 arguments を渡す)
// xpnd ... 仕分け方の配列
////////////////////////////////////////////////////////////////////////////////
// 仕分け方(xpnd)の仕様
// xpnd
// [ArgSpec, ArgSpec, ... , ArgSpec]
// ArgSpec
// {
// vartype:,
// inscheck:,
// insclass:,
// optional:,
// dependend:,
// errmsg:,
// proc:,
// }
// vartype:
// string型、引数の型を指定する(e.g. "string", "number")
// 必須
// inscheck:
// boolean型、instanceofでの型チェックを行うか
// 省略可能、省略時はfalse
// insclass:
// function型、inscheck:がtrueの場合に検査するクラス(e.g. Array)
// inscheckがtrueの場合は必須、それ以外の場合はこの指定は無視される
// optional:
// boolean型、この引数が省略可能かを示す
// 省略可能、省略時はfalse
// dependend:
// object型(配列、Arrayのインスタンス)、他の引数との関係を示す
// この引数が現れる『直前』に現れる必要のある引数仕様(ArgSpec)の
// xpndの配列内でのインデックスを並べた配列を指定する
// xpndは順番に処理されるためインデックスはこの引数より前のインデックスを指定する
// 関係対象の全ての引数が省略可能でありかつ全て省略された場合この引数も省略されるとみなされる
// 省略可能、省略時は他の引数とは無関係の引数とみなされる
// errmsg:
// string型、この引数が省略不可能な場合に例外スローするメッセージ
// 次のいずれにも該当しないときこの引数が省略不可能な場合である
// ・optionalにtrueが指定されている
// ・dependentで指定されたインデックスが直前に現れてない
// 省略可能、省略時はundefinedがスローされることになる
// proc:
// function型、この引数が存在した場合に呼び出す関数(この引数をこの関数第一引数に渡す)
// 必須
////////////////////////////////////////////////////////////////////////////////
parseArguments = (function() {
function checkSkip(x, p) {
var i, len;
if (x.dependent) {
len = x.dependent.length;
for (i = 0; i < len; i++) {
if (x.dependent[i] === p) { break; }
}
return i === len && len > 0;
}
return false;
}
function parseArguments(args, xpnd) {
var apos = 0;
var xpos = 0;
var lastxpos = -1;
var dep;
while (xpos < xpnd.length && apos < args.length) {
if (checkSkip(xpnd[xpos], lastxpos)) {
xpos++;
continue;
}
if (xpnd[xpos].vartype === typeof args[apos]) {
if (xpnd[xpos].inscheck !== true || args[apos] instanceof xpnd[xpos].insclass) {
xpnd[xpos].proc(args[apos]);
lastxpos = xpos;
xpos++;
apos++;
continue;
}
}
if (xpnd[xpos].optional) {
xpos++;
} else {
throw xpnd[xpos].errmsg;
}
}
while (xpos < xpnd.length) {
if (xpnd[xpos].optional || checkSkip(xpnd[xpos], lastxpos)) {
xpos++;
continue;
}
throw xpnd[xpos].errmsg;
}
return apos;
}
return parseArguments;
})();
<!DOCTYPE html>
<html>
<head>
<meta charset="utf8" />
<title>test parse arguments</title>
<script type="text/javascript" src="./parsearguments.js"></script>
</head>
<body>
<h1>test parse arguments</h1>
<script type="text/javascript">
var piyo = {"log": function(s) {
document.write("<" + "div" + ">" + s + "<" + "/" + "div" + ">");
}};
function hoge() {
piyo.log('-------------------------------------');
piyo.log('call hoge' + (function (a) {
var i, r = '(';
for (i = 0; i < a.length; i++) {
if (i > 0) r += ', ';
if ('string' === typeof a[i]) r += '"';
if (a[i] instanceof Array) r += 'Array[';
r += a[i];
if ('string' === typeof a[i]) r += '"';
if (a[i] instanceof Array) r += ']';
}
return r + ')';
})(arguments));
var xpnd = [
{ "vartype" : "string"
, "inscheck" : false
, "optional" : true
, "dependent": []
, "proc" : function (s) { piyo.log('first: ' + s); }
, "errmsg" : ""
},
{ "vartype" : "string"
, "inscheck" : false
, "optional" : true
, "dependent": [0]
, "proc" : function (s) { piyo.log('second: ' + s); }
, "errmsg" : ""
},
{ "vartype" : "boolean"
, "inscheck" : false
, "optional" : true
, "dependent": [0, 1]
, "proc" : function (s) { piyo.log('third: ' + s); }
, "errmsg" : ""
},
{ "vartype" : "number"
, "inscheck" : false
, "optional" : false
, "dependent": []
, "proc" : function (s) { piyo.log('forth: ' + s); }
, "errmsg" : "require numeric value (forth)"
},
{ "vartype" : "number"
, "inscheck" : false
, "optional" : true
, "dependent": []
, "proc" : function (s) { piyo.log('fifth: ' + s); }
, "errmsg" : ""
},
{ "vartype" : "object"
, "inscheck" : true
, "insclass" : Array
, "optional" : true
, "dependent": []
, "proc" : function (s) { piyo.log('sixth: ' + s); }
, "errmsg" : ""
},
{ "vartype" : "boolean"
, "optional" : false
, "dependent": [5]
, "proc" : function (s) { piyo.log('seventh: ' + s); }
, "errmsg" : "need with sixth Array (seventh)"
},
{ "vartype" : "object"
, "inscheck" : false
, "optional" : true
, "proc" : function (s) { piyo.log('eighth: ' + s); }
, "errmsg" : ""
}
];
parseArguments(arguments, xpnd);
}
// test
hoge(5);
hoge('piyo', 10);
hoge('foo', 'bar', 15);
hoge('ask', 'boss', false, 20);
hoge('fuga', true, 33);
hoge(99, 100);
hoge('Like', 87, 45);
hoge('MAKE', 87, false);
hoge('xyz', 'ABC', true, 123, 987);
try { hoge(false, 45); } catch (e) { piyo.log('Exception: ' + e); }
try { hoge('a', 'b', 'c', 32); } catch (e) { piyo.log('Exception: ' + e); }
try { hoge('you', true, 'me', 45); } catch (e) { piyo.log('Exception: ' + e); }
hoge('arere?', 777, [2, 3, 5, 7], false);
hoge('why jap?', 119, 110, [11, 13, 17, 19], true);
hoge('damepo', 4649, {"length": 0});
try { hoge('buru', 500, [10, 20, 30]); } catch (e) { piyo.log('Exception: ' + e); }
/* result output
-------------------------------------
call hoge(5)
forth: 5
-------------------------------------
call hoge("piyo", 10)
first: piyo
forth: 10
-------------------------------------
call hoge("foo", "bar", 15)
first: foo
second: bar
forth: 15
-------------------------------------
call hoge("ask", "boss", false, 20)
first: ask
second: boss
third: false
forth: 20
-------------------------------------
call hoge("fuga", true, 33)
first: fuga
third: true
forth: 33
-------------------------------------
call hoge(99, 100)
forth: 99
fifth: 100
-------------------------------------
call hoge("Like", 87, 45)
first: Like
forth: 87
fifth: 45
-------------------------------------
call hoge("MAKE", 87, false)
first: MAKE
forth: 87
-------------------------------------
call hoge("xyz", "ABC", true, 123, 987)
first: xyz
second: ABC
third: true
forth: 123
fifth: 987
-------------------------------------
call hoge(false, 45)
Exception: require numeric value (forth)
-------------------------------------
call hoge("a", "b", "c", 32)
first: a
second: b
Exception: require numeric value (forth)
-------------------------------------
call hoge("you", true, "me", 45)
first: you
third: true
Exception: require numeric value (forth)
-------------------------------------
call hoge("arere?", 777, Array[2,3,5,7], false)
first: arere?
forth: 777
sixth: 2,3,5,7
seventh: false
-------------------------------------
call hoge("why jap?", 119, 110, Array[11,13,17,19], true)
first: why jap?
forth: 119
fifth: 110
sixth: 11,13,17,19
seventh: true
-------------------------------------
call hoge("damepo", 4649, [object Object])
first: damepo
forth: 4649
eighth: [object Object]
-------------------------------------
call hoge("buru", 500, Array[10,20,30])
first: buru
forth: 500
sixth: 10,20,30
Exception: need with sixth Array (seventh)
*/
</script>
</body>
</html>
@neetsdkasu
Copy link
Author

車輪の何チャラ

@neetsdkasu
Copy link
Author

そういや配列に対応してないな

@neetsdkasu
Copy link
Author

optionalの評価を===falseやめたほうが良さそう

@neetsdkasu
Copy link
Author

===falseをやめた

@neetsdkasu
Copy link
Author

gist上で見るとtypeとかcalleeとか色付いてるから名前変えたほうが良さそう

@neetsdkasu
Copy link
Author

calleeからprocに変えたけどこれもアカンかったか

@neetsdkasu
Copy link
Author

どうもprocの色の変化は問題なさそう

var x = { "baz":4,"bar": function() {alert(234); }, "xk": 123 };
var k = hoge.foo(xx);

@neetsdkasu
Copy link
Author

配列は・・・まぁ別途個別に判定関数を受け取ってチェックするのが妥当か?

@neetsdkasu
Copy link
Author

instanceofは右が関数型なら何でもおkぽさげ?

@neetsdkasu
Copy link
Author

関数に分離できるのか

@neetsdkasu
Copy link
Author

これ微妙に意味パースと違うんだよなあ・・・微妙ってか全く違う

@neetsdkasu
Copy link
Author

パースではなくキチンと意味ピタッとしそうな名前探さなくっちゃ

@neetsdkasu
Copy link
Author

https://git.io/vi20U
これでの使い方を見ると何かデジャヴを感じるのよな~
たぶんどっかでこういう引数分解のやつ見てて、そのうろ覚えとかな感じで車輪しちゃったわけかもな~

@neetsdkasu
Copy link
Author

たーぶんー
ジェークエリーってやつかー
ジェークエリーってのを使ったことは一度もないけど
他人の作ったサイトのhtmlやjsのソース眺めることはごくたまにあるからにゃーそんときだにゃー

@neetsdkasu
Copy link
Author

これも使いたい人たぶん俺以外にいないと確実に思うけど一応ライセンスの一行入れておいたー MIT Licenseなー

The MIT License (MIT)

Copyright (c) 2016 Leonardone @ NEETSDKASU

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

@neetsdkasu
Copy link
Author

これ parsearguments.js にxpndの形式に関する説明コメント書き入れたほうが親切ぽさげだよな~

@neetsdkasu
Copy link
Author

中々にバグが潜んでる

@neetsdkasu
Copy link
Author

そういやfindIndexみたいなのあった気がするにゃあ

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment