2016-04-28 5 views
2

私はルビーに新しいですので、私が最初に私の問題の状況を説明してみましょう: 私は、次のキー/値のペアを持っている入力としてJSONを持っている:polymorphismを使用して文字列を比較するswitch文を削除するにはどうすればよいですか?

{ 
"service": "update" 
} 

値は、例えば、多くの異なる値を持っています:など 次異なる要求を処理するメソッドのxがあり、削除、挿入します。私はまだ "のことを思い出す(文字列値をチェックするために、switchステートメントを使用する必要があるということです何悩ませている

def x(input) 

    case input[:service]  
    services = GenericService.new 

    when "update" 
    result = services.service(UpdateService.new,input) 
    when "insert" 
    result = services.service(InsertService.new,input) 
    when "delete" 
    result = services.service(DeleteService.new,input) 
    .... 
    .... 
    else 
    raise "Unknown service" 
    end 
    puts JSON.pretty_generate(result)  
end 

'ugh ..のインスタンス)。よりクリーンな方法(スイッチを使用する必要はありません)はありますか?

最後に私は質問に答えて検索しようとしましたが、私がそれを逃した場合は、関連する質問にコメントすることはできませんでした。

アップデート:私は多分に考えていたが、次のように関連するクラス名に文字列をキャスト:How do I create a class instance from a string name in ruby?と、結果= services.services(x.constantize.new、入力)を呼び出し、その後、クラス名はofcourseのに必要jsonの入力と一致します。

答えて

3

あなたのような何か試すことができます。

def x(input) 

    service_class_name = "#{input[:service].capitalize}Service" 
    service_class = Kernel.const_get(service_class_name) 
    service_class.new(input).process 

end 

また、これが有効なサービスクラス名であるかどうかを確認することもできます。

サービスをGenericServiceに渡す理由がわかりません。これは奇妙に思えます。サービスを仕事にさせてください。

+0

のGenericServiceは、今怠慢になりません、insertなど –

+0

Kernal.const_getを特定のモジュールYに制限するにはどうすればよいですか? –

+0

Nevermindはそれを持っています:) Object.const_get(module_name).const_get(class_name).new –

1

名前でクラスを具体化しようとしている場合は、実際に多態性ではなく反射について話しています。あなたはこの方法でこれを達成することができRubyでは

byName = Object.const_get('YourClassName') 

か、Railsのアプリで

byName= 'YourClassName'.constantize 

希望される場合は、このことができます

0

ただ、最初の思考が、あなたが行うことができます:私は直接更新を呼び出すことができますので、皆さんのよう

eval(services.service("#{input[:service].capitalize}Service.new, #{input})") if valid_service? input[:service] 

def valid_service? 
    w%(delete update insert).include? input[:service] 
end 

は間違いなく叫びは、evalは介護の多くを使用する必要があります

+1

Nevereverは "eval"を使用します。それは「悪」です。 –

+0

@pascalbetz - 私はあなたがevalの問題に遭遇することに同意します。存在しないものを取得しようとするとエラーがスローされるので、const_getを好むので、サニティチェックが必要ですインバウンド。 – ABrowne

関連する問題