MochiKit を使う際に、追加している関数を晒してみる(その2.partial)
id:cooldaemon:20070429:1177857285 の続き。
Mochikit.Base.partial は、前方から引数を束縛するのですが、任意の位置の引数を束縛したかったので、my_partial を作ってみました。
source の前に実例
var base_func = function () { map(function (arg, i) {log(i + ' = ' + arg);}, arguments, count()); }; var lazy_base_func = function () { var str = ''; forEach(arguments, function (arg) {str += arg;}) return str; }; var new_func = my_partial(base_func, 'a', hole, 'c', hole, lazy(lazy_base_func, 2)); new_func('b', 'd', 'e', 'f', 'g');
上記を実行すると…
0 = a 1 = b 2 = c 3 = d 4 = ef 5 = g
と出力されます。
Mochikit.Base.partial と似ている箇所
my_partial は、第一引数に引数を束縛したい関数、第二引数以降に束縛したい引数を渡して使います。
Mochikit.Base.partial と明らかに異なる箇所
hole を第二引数以降にすると、その箇所に、新しく my_partial で作った関数の引数が渡されます。
また、lazy 関数の戻り値を引数として渡すと、my_partial で作った関数を実行する度に、lazy 関数の第一引数として渡した関数を実行し、その戻り値を、my_partial で作った関数の引数とします。
lazy 関数の第二引数は、第一引数に渡した関数に、my_partial で作った関数に渡した引数を幾つ渡すのか?を指定します。(省略すると、0 個になります)
で、source
下記、名前空間無視してます。ゴメンナサイ。
その他の突っ込み大歓迎です。
var Lazy = function (func) { var m = MochiKit.Base; this.func = func; this.arg_count = m.isUndefinedOrNull(arguments[1]) ? 0 : arguments[1]; }; var hole = {}; var lazy = function (func, arg_count) { return new Lazy(func, arg_count); }; var my_partial = function (func) { var m = MochiKit.Base; var it = MochiKit.Iter; var base_args = m.extend(null, arguments, 1); return function () { var args = arguments; args.shift = Array.prototype.shift; var new_args = []; it.forEach(base_args, function (arg) { if (arg !== hole && !(arg instanceof Lazy)) { new_args.push(arg); return; } if (arg == hole) { if (!m.isUndefinedOrNull(args[0])) { new_args.push(args.shift()); } return; } var lazy_args = []; for (var count = 0; count < arg.arg_count; count++) { if (m.isUndefinedOrNull(args[0])) { break; } lazy_args.push(args.shift()); } new_args.push(arg.func.apply(this, lazy_args)); }); it.forEach(args, function (arg) { new_args.push(arg); }); func.apply(this, new_args); } }
関数呼び出す度に、こんなんしてたら重いなぁ…。