2015-07-03 69 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