ソースコード:Reduce(object, object)
ファイル Builtin.cs には、別の関数 reduce の定義が含まれます。
# IronPython-1.1.2/Src/IronPython/Modules/Builtin.cs
[PythonType("__builtin__")]
public static partial class Builtin {
...
[PythonName("reduce")]
public static object Reduce(object func, object seq) {
IEnumerator i = Ops.GetEnumerator(seq);
if (!i.MoveNext()) {
throw Ops.TypeError("reduce() of empty sequence with no initial value");
}
object ret = i.Current;
while (i.MoveNext()) {
ret = Ops.Call(func, ret, i.Current);
}
return ret;
}
次のテストケースを試すと、このコードの意味を理解するのに役立ちます。
>>> reduce(lambda acc,e: e+acc, "")ここでは、例外 TypeError が発生して、エラーメッセージが出力されます。これは、メソッド本体にある、Ops.TypeError の引数と同じ文字列です。例外 TypeError を生成してメッセージを表示したいときに、Ops.TypeError を利用するだけです。
Traceback (most recent call last):
File "", line 1, in
reduce(lambda acc,e: e+acc, "")
TypeError: reduce() of empty sequence with no initial value>>> reduce(lambda acc,e: acc+e, [])
Traceback (most recent call last):
File "", line 1, in
reduce(lambda acc,e: acc+e, [])
TypeError: reduce() of empty sequence with no initial value
if (!i.MoveNext()) {
throw Ops.TypeError(...);
}
この条件式から、次の要素が得られないときに、例外を生成しているのが分かります。なぜなら、空文字列 "" や空リスト [] は、要素を含まないからです。
これに続くメソッド本体は、前述した Reduce(object, object, object) とほぼ同じです。これで、その動作を理解するのに必要なコードを読破したことになります。