6

開発中のコマンドラインRubyアプリがあり、そのユーザーがプロセスの一部でフィルターとして実行されるコードを提供できるようにしたいと考えています。基本的に、アプリケーションはこれを行います。

  1. 一部のデータを読み込む
  2. フィルタが指定されている場合は、それを使用してデータをフィルタリングします
  3. データを処理する

フィルタリングプロセス(ステップ2)をできるだけ柔軟にしたいと思います。

私の考えでは、ユーザーは、私が定義したインターフェースを実装するオブジェクトを指すように既知の定数を設定するRubyファイルを提供できると考えていました。

# user's filter

class MyFilter
  def do_filter(array_to_filter)
    filtered_array = Array.new
    # do my filtering on array_to_filter
    filtered_array
end 

FILTER = MyFilter.new

私のアプリのコードは次のようになります。

array_that_might_get_filtered = get_my_array()
if (options.filter_file)
  require options.filter_file
  array_that_might_get_filtered = FILTER.do_filter(array_that_might_get_filtered)
end

これはうまくいくでしょうが、それは安っぽく感じます、そしてそれをするより良い方法があるべきであるように思われます。また、既知のクラスに既知の名前のメソッドを追加する形式でフィルターを使用することも検討しましたが、それも正しくないようでした。

このためのRubyのより良いイディオムはありますか?

4

3 に答える 3

4

コマンドラインと規則を組み合わせて使用​​するだけです。

フィルタが指定されている場合は、それを使用してデータをフィルタリングします

コマンドラインでフィルターを指定すると思いますか?では、このようにアプリケーションを呼び出すでしょうか?

ruby dataprocessor.rb custom_filter

その場合、クラス名が渡されたものと一致する必要がある「api」を定義できます-例で説明したとおりです。

さらに一歩進めると、CustomFilterRuby の を使用してクラスを検索するロジックを作成できますdefined?。見つからない場合は (または適切なバリエーション) を探してcustom_filter.rbそのファイルをロードしてから、再試行します。

これにより、拡張性が大幅に向上します。フィルター クラスを好きなだけ作成し、それらを独自の .rb ファイルに入れ、Ruby が見つけられる場所に配置できるからです。定義済みの定数も必要ありません。唯一の制約は

  1. クラス名はファイル名 (の変形) と一致する必要があります。これは ruby​​ の慣習であるため、おそらく既に実行しているはずです。
  2. do_filterメソッドなど、事前定義されたメソッドが必要です

ちなみに、これはレールがモデルを要求するために行うことと非常によく似ており、SomeModel常にrequire app/models/some_model最初に行う必要がなく、単に使用できる理由です :-)`

于 2008-10-30T20:19:20.253 に答える
0

ストラテジーパターンの仕事のように見えます。rubyにはファーストクラスのオブジェクトとしての関数があるため、そのカスタムフィルター関数をオンデマンドで呼び出すために、フィルター関数を渡して配列に記憶させることができます。

于 2008-10-30T19:50:52.383 に答える
0
# user code
USER_FILTER = lambda { |value| value != 0xDEADBEEF }

# script code
load( user_code );
FILTER = ( const_defined?(:USER_FILTER) ? USER_FILTER : lambda { true } )

output_array = input_array.filter(&FILTER)
于 2008-10-30T20:28:23.837 に答える