2015-07-03 65 views
5

我在通過散列值搜索我的值是方法時遇到問題。我只是不想運行plan_type匹配鍵的方法。在方法值中搜索紅寶石中的散列值

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 

目前,如果我在「酒吧」通過爲plan_type,每一個方法將被運行,我怎麼能只只運行plan_is_bar方法?

+0

有很多的方式來實現你似乎想(呼叫根據命名類型或其它邏輯的方法)的影響。如果你要立即調用這個方法,像這樣的哈希可能不是最簡單的方法。但是,如果您想延遲撥打電話,則可能會很有用。 –

回答

8

這個變體呢?

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 

使用lambda表達式或特效是讓事情偷懶的好方法,因爲它們被執行時,才收到由於這一方法call

可以使用->(拉姆達文字)作爲輕量級封裝周圍可能重計算和call它只有當你需要。

+5

你也可以解釋一下lambda表達式,以及他們如何在返回正確值之前用他的代碼完成所有可能的方法調用來解決OP的問題。最重要的是,你並沒有將這些值寫入方法中(這在Ruby中並不可行),但是包含正確方法調用的Proc(並且這些也是閉包)。 –

+0

'method'的參數有一個小問題,因爲'method(:har,「bob」)'會引發'ArgumentError'異常。我通過給予'plan'一個任意的默認值來解決這個問題。除了@ Neil的觀點,你只需要創建(然後調用)一個lambda:'def method(plan_type,plan = nil,user);如果plan_type ==:har; - >(user){plan_is_har(user)} .call user;其他;案例plan_type; when:foo then - >(plan,user){plan_is_foo(plan,user)}; when:bar then - >(plan,user){plan_is_bar(plan,user)}; when:waa then - >(plan,user){plan_is_waa(plan,user)};結束計劃,用戶;結束; end'。 –

1

一個非常簡單的解決方案:

代碼

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 

你當然可以使用散列而不是case聲明。

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