哈希上的Ruby case语句?

Mic*_*son 8 ruby hash branch case-statement

这听起来很奇怪,但我很乐意这样做:

case cool_hash
  when cool_hash[:target] == "bullseye" then do_something_awesome
  when cool_hash[:target] == "2 pointer" then do_something_less_awesome
  when cool_hash[:crazy_option] == true then unleash_the_crazy_stuff
  else raise "Hell"
end
Run Code Online (Sandbox Code Playgroud)

理想情况下,我甚至不需要再次引用has,因为它就是case语句的内容.如果我只想使用一个选项,那么我会"case cool_hash [:that_option]",但我想使用任意数量的选项.另外,我知道Ruby中的case语句只评估第一个真正的条件块,有没有办法覆盖它来评估每个块都是真的,除非有中断?

mar*_*ery 17

你也可以使用lambda:

case cool_hash
when -> (h) { h[:key] == 'something' }
  puts 'something'
else
  puts 'something else'
end
Run Code Online (Sandbox Code Playgroud)

  • 正是我要找的! (2认同)

Dav*_*son 6

您的代码非常接近有效的 ruby​​ 代码。只需删除第一行的变量名称,将其更改为:

case
Run Code Online (Sandbox Code Playgroud)

但是,无法覆盖 case 语句来评估多个块。我认为你想要的是使用if语句。代替 a break,您使用return跳出该方法。

def do_stuff(cool_hash)
  did_stuff = false

  if cool_hash[:target] == "bullseye"
    do_something_awesome
    did_stuff = true
  end

  if cool_hash[:target] == "2 pointer"
    do_something_less_awesome
    return  # for example
  end

  if cool_hash[:crazy_option] == true
    unleash_the_crazy_stuff
    did_stuff = true
  end

  raise "hell" unless did_stuff
end
Run Code Online (Sandbox Code Playgroud)


Dat*_*Don 5

我认为,以下是做你想做的事情的更好方法。

def do_awesome_stuff(cool_hash)
  case cool_hash[:target]
    when "bullseye"
      do_something_awesome
    when "2 pointer"
      do_something_less_awesome
    else
     if cool_hash[:crazy_option]
      unleash_the_crazy_stuff
     else
      raise "Hell"
     end
  end
end
Run Code Online (Sandbox Code Playgroud)

即使在 case 的 else 部分,如果有更多条件,您也可以使用 'case Cool_hash[:crazy_option]' 而不是 'if'。我更喜欢你在这种情况下使用“if”,因为只有一个条件。


小智 2

ruby​​ 3.0中,您可以通过模式匹配执行以下操作

# assuming you have these methods, ruby 3 syntax
def do_something_awesome = "something awesome "
def do_something_less_awesome = "something LESS awesome"
def unleash_the_crazy_stuff = "UNLEASH the crazy stuff "
Run Code Online (Sandbox Code Playgroud)

你可以做

def do_the_thing(cool_hash)
  case cool_hash
  in target: "bullseye" then do_something_awesome
  in target: "2 pointer" then do_something_less_awesome
  in crazy_option: true then unleash_the_crazy_stuff
  else raise "Hell"
  end
end
Run Code Online (Sandbox Code Playgroud)

将返回

do_the_thing(target: "bullseye")
=> "something awesome "

do_the_thing(target: "2 pointer")
=> "something LESS awesome"

do_the_thing(crazy_option: true)
=> "UNLEASH the crazy stuff "
Run Code Online (Sandbox Code Playgroud)

ruby​​ 2.7中它仍然有效

# need to define the methods differently
def do_something_awesome; "something awesome "; end
def do_something_less_awesome; "something LESS awesome"; end
def unleash_the_crazy_stuff; "UNLEASH the crazy stuff "; end

# and when calling the code above to do the switch statement
# you will get the following warning
warning: Pattern matching is experimental, and the behavior may change
         in future versions of Ruby!
Run Code Online (Sandbox Code Playgroud)