2

このコードを考えると:

a = {1=>2}
m = a.method(:[])

私は今使用できることを知っています:

value = m.call(1)

2を返します。問題は、次のようにメソッドを直接呼び出すことができるように、何を変更する必要があるかということです。

m.call()

そしてそれはパラメータとして送信される1を取得しますか?次のようなものを書くことができれば素晴らしいでしょう:

m = a.method(:[],1) # where the symbol is the method, and 1 will be the parameter it will be called with

重要なのは、いくつかのオブジェクトが作成されるまでスクリプトの特定の部分の実行を遅らせたいということです。ラムダを使用するようにすべてを書き直さないようにしたいのです。

4

3 に答える 3

3

基本的に、必要なのは関数をカリー化する方法です。

http://en.wikipedia.org/wiki/Curry_function

これは、さまざまな方法で実行できます。そのうちの 1 つを次に示します。

def curry(method, *params)
  lambda { send method, *params }
end

これを Hash のメタクラス、または一部のオブジェクトに含めたいモジュールなどに追加できます。その後、それを呼び出すと、必要なユースケースになります。

irb(main):001:0> a = {1 => 2}
=> {1=>2}
... # add curry to Hash's metaclass
irb(main):011:0> m = a.curry :[], 1
=> #<Proc:0xb76e2154@(irb):8>
irb(main):012:0> m.call
=> 2
于 2009-11-10T16:53:33.693 に答える
0

メソッドを呼び出しているオブジェクトにメソッド パラメーターをアタッチし、メソッドにインスタンス変数としてアクセスさせる必要があるようです。

簡単なリファクタリング手順については、次のとおりです。

  • メソッド パラメーターごとに 1 つの新しいインスタンス変数を導入します。
  • インスタンス変数に新しいアクセサーを導入します。
  • パラメータが指定されていない場合は、インスタンス変数を使用するようにメソッドをリファクタリングします。
  • メソッド呼び出しの前のある時点で、呼び出しコードをリファクタリングして、アクセサーを介してインスタンス変数を設定します。
  • メソッド呼び出しでパラメーターを渡さないように、呼び出しコードをリファクタリングします。

例として、呼び出しコードを次のようにリファクタリングします。

widget = Widget.new
assembly_method = widget.method(:assemble)
# Time passes...
assembly_method.call(:electric, :smooth)

次のように動作します。

widget = Widget.new
widget.frombulator = :electric
widget.jazzifier = :smooth
assembly_method = widget.method(:assemble)
# Time passes...
assembly_method.call

それは魅力的でも賢いものでもありませんが、その意図を表現するコードになり、実際の問題、つまりモデルに何かが欠けているという問題に対処できる可能性が高くなります。

于 2009-11-10T16:09:38.807 に答える