ラムダに関する上記のrkjの回答にコメントしました。このコードは、あなたが求めた例を示しています。
def abs(n); (n < 0) ? -n : n; end
def square(n); n * n; end
def average(x, y); (x + y) / 2; end
def fixed_point(x, point, process, test)
return point if test.call(x, point)
fixed_point(x, process.call(x, point), process, test)
end
def sqrt(n)
process = lambda {|n,g| average g, (n/g) }
test = lambda {|n,g| abs(square(g) - n) < 0.001}
fixed_point(n, 1.0, process, test)
end
最初に注意すべき点は、このfixed_point
メソッドは、特定のテストに合格するまで、一部のデータにプロセスを段階的に適用するという一般的な考え方を処理することです。このsqrt
関数は、平方根を見つけるプロセスと、いつ満足するかを判断するためのテストを定義します。これらの「手順」は、他の形式のデータと同じように渡されるため、fixed_point
魔法のように機能します。
プロセスを一時的に保存してテストする代わりに、すべてを匿名にすることができます。次のように書き直すことができsqrt
ます。
def sqrt(n)
fixed_point( n, 1.0,
lambda {|n,g| average g, (n/g)},
lambda {|n,g| abs(square(g) - n) < 0.001} )
end
この機能がなければ、プロセスとテストの両方を個別の関数として定義し、sqrt_fixed_point
それらを呼び出す特別な関数を作成する必要があります。私が知る限り、Java は Functors を使用して同様のことを行うことができますが、コメントするのに十分な知識がありません。私がブログなどで見たコンセンサスは、Java はこれを非常に複雑にするため、試しただけで鼻血が出てしまうというものです。
もちろん、Ruby が提供するもう 1 つのオプションは、メタプログラミングです。sqrt
正しいプロセスとテストを使用して(オンザフライで)書き換えられるように書き換えることができfixed_point
ますが、これはおそらく機能の悪用です:-)
ps。JoelOnSoftware のリンクが掲載されていることは、繰り返し説明する価値があります。http://www.joelonsoftware.com/items/2006/08/01.html