2015-07-03 23 views
5

Değerleri olan bir Ruby ile bir karma boyunca arama Değerlerim yöntemleri nerede bir karma arama yaparken bir sorun yaşıyorum. Sadece plan_type anahtarın eşleştiği yöntemi çalıştırmam.Yöntemler

Ben plan_type olarak "bar" geçirirseniz Şu anda, her yöntem idare edilecek
def method(plan_type, plan, user) 
    { 
    foo: plan_is_foo(plan, user), 
    bar: plan_is_bar(plan, user), 
    waa: plan_is_waa(plan, user), 
    har: plan_is_har(user) 
    }[plan_type] 
end 

, nasıl sadece plan_is_bar yöntemi çalıştırabilirsiniz?

+0

Eğer (adlandırılmış türü veya diğer mantığı bağlı bir yöntemi çağırmak) istediğiniz gibi görünüyor etkiyi elde etmek için birçok yol vardır. Yöntemi hemen çağırırsanız, bunun gibi bir Hash en kolay yol olmayabilir. Ancak, daha sonraya kadar arama yapmak ertelemek istiyorsanız, yararlı olabilir. –

cevap

8

Bu varyantdan ne haber? bunlar yürütülür çünkü lambdas veya procs kullanarak

def method(plan_type, plan, user) 
    { 
    foo: -> { plan_is_foo(plan, user) }, 
    bar: -> { plan_is_bar(plan, user) }, 
    waa: -> { plan_is_waa(plan, user) }, 
    har: -> { plan_is_har(user) } 
    }[plan_type].call 
end 

onlar etrafında muhtemelen -> (lamda literal) olarak hafif kapsayıcı kullanabilir Bu nedenle yöntemini call

almak sadece, işler tembel yapmak için iyi bir yoldur Ağır hesaplamalar ve call sadece ihtiyacınız olduğunda.

+5

Ayrıca lambdalar hakkında biraz açıklayabilir ve OP'in problemini, doğru değeri döndürmeden önce tüm olası yöntem çağrılarını yapan koduyla nasıl çözdüğünü açıklayabilirsiniz. En önemlisi, buradaki değerleri (Ruby'de gerçekten mümkün olmayan) yöntemlere dönüştürmediniz, fakat doğru yöntem çağrılarını içeren Proks (ve bunlar aynı zamanda kapaklar). –

+0

"method" argümanları ile ilgili küçük bir sorun var, "method (: har," bob ")' bir 'ArgumentError 'istisnası oluşturacaktır. Ben 'plan' rasgele bir varsayılan değer vererek bunu ele. @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ eğer plan_type ==: har; -> (kullanıcı) {plan_is_har (kullanıcı)} .call kullanıcı; Başka; durum plan_türü; ne zaman: foo o zaman -> (plan, kullanıcı) {plan_is_foo (plan, kullanıcı)}; ne zaman: bar sonra -> (plan, kullanıcı) {plan_is_bar (plan, kullanıcı)}; ne zaman: waa o zaman -> (plan, kullanıcı) {plan_is_waa (plan, kullanıcı)}; end.call planı, kullanıcı; son; Sonu '. –

1

Çok basit çözümü: Elbette bir case deyimi yerine bir karma kullanabilirsiniz

def method(plan_type, plan=nil, user) 
    m = 
    case plan_type 
    when "foo" then :plan_is_foo 
    when "bar" then :plan_is_bar 
    when "waa" then :plan_is_waa 
    when "har" then :plan_is_har 
    else nil 
    end 

    raise ArgumentError, "No method #{plan_type}" if m.nil? 
    (m==:plan_is_har) ? send(m, user) : send(m, plan, user) 
end 

Kodu.

Örnek

def plan_is_foo plan, user 
    "foo's idea is to #{plan} #{user}" 
end 

def plan_is_bar plan, user 
    "bar's idea is to #{plan} #{user}" 
end 

def plan_is_waa plan, user 
    "waa's idea is to #{plan} #{user}" 
end 

def plan_is_har user 
    "har is besotted with #{user}" 
end 

method "foo", "marry", "Jane" 
    #=> "foo's idea is to marry Jane" 

method "bar", "avoid", "Trixi at all costs" 
    #=> "bar's idea is to avoid Trixi at all costs" 

method "waa", "double-cross", "Billy-Bob" 
    #=> "waa's idea is to double-cross Billy-Bob" 

method "har", "Willamina" 
    #=> "har is besotted with Willamina" 

method "baz", "Huh?" 
    #=> ArgumentError: No method baz