解決編:その理解は確かか
ここまでの理解が確かなら、その理由を説明できるはずです。
if (!i.MoveNext()) {
throw Ops.TypeError(...);
}
ex1 では、第2引数が "A" なので、次の要素 "A" に進めます。すると、条件式 !i.MoveNext() は成立しないので、例外を生成しません。
object ret = i.Current;
while (i.MoveNext()) {
ret = Ops.Call(func, ret, i.Current);
}
return ret;
ret は、要素 "A" を保持します。次の要素が残っていないので、先に進めません。すると、条件式 i.MoveNext() は成立しないので、ret がリターン値になります。
TypeError: 'NoneType' object is not callable
ex3 で、このエラーメッセージを出力するのは、第1引数に None を指定したからです。None には、メソッド呼び出しを適用できません。
Python との違いはあるか
関数の動作に微妙な違いがあるので、Python/IronPython の一貫性を保つには、細心の注意が必要です。Python でその動作を確認したのは、それを確認するためでした。
読者への課題
さらにその理解を深めるために、読者のみなさんへの課題を提供します。
《課題1》ex2 では失敗しても、これに第3引数を追加するだけで、
>>> reduce(None, "", 0)0
0 がリターン値になるのは、なぜですか。□
《課題2》ex1 では成功しても、これに第3引数を追加するだけで、
>>> reduce(None, "A", "@")
Traceback (most recent call last):
File "", line 1, in
reduce(None, "A", "@")
TypeError: 'NoneType' object is not callable
エラーメッセージを出力するのは、なぜですか。□