如何编写延迟评估switch语句?

时间:2009-11-18 17:06:32

标签: ruby

很长一段时间我拼命想要让它发挥作用,我用Google搜索,我已经修改了,我已经问了一些当地的Rubyists(虽然不是pdx.rb,但我确实应该这样做。)

我们试图在工作中做这样的事情:

case user.roles.included? (... magic ...) 
when ['admin', 'editor'] 
  then ...
when ['anonymous'] 
  then ...
end

所以你可以看到case的感觉,但因为它没有像El所说的那样使用===,所以它不起作用。我知道我可以使用if但感觉就像应该使用case的地方。

2 个答案:

答案 0 :(得分:3)

case 
  when x == 16
    puts 'hi'
  when x.is_a?(Object)
    puts 'obj'
end

如果我真的理解了这个问题,您只需要在x关键字后删除case变量。

lambda代码不起作用,因为lambda只返回参数。

names_l.call(names)
# => {:name => 'Terry'}

就像运行以下代码一样:

case {:name => 'Terry'}
  when 'Terry'
    puts "Success!"
end

{:name => 'Terry'}不等于'Terry'

答案 1 :(得分:3)

when使用===运算符将给定case的值与给予when的参数进行比较。当出现在与then语句不同的行时,when也是不必要的。正在尝试执行的操作的正确代码是:

case x
when 16
  puts 'hi'
when Object
  puts 'obj'
end

至于问题的新增内容:

case user.roles.included? (... magic ...) 
when ['admin', 'editor'] 
  ... 
when ['anonymous'] 
  ... 
end

这不起作用,因为数组的===未映射到include。我不确定Array的===运算符来自哪里,甚至不知道它的作用,但你可以覆盖它来提供你想要的功能。

根据上面的代码判断,如果其中一个用户角色与数组匹配,则需要case触发。这将覆盖Array#===来执行此操作:

class Array
  def === other_array
    ! (other_array & self).empty?
  end
end

case user.roles
when ['admin', 'editor'] 
  ... 
when ['anonymous'] 
  ... 
end

警告:根据您覆盖Array#===的位置,这可能会产生无法预料的后果,因为它会更改该范围内的所有数组。鉴于===是从Object继承的,它是==的别名,我不认为这是一个大问题。

===与旧版===不同的地方:

  • 如果任何一个数组是子集或重新排序另一个数组,则新===将返回true。
  • 如果两个数组相同(订单和内容),则旧===将仅返回true。

据我所知,case / when是唯一可以在数组上隐式调用===的时间。