Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby case statement on a hash?

This is going to sound weird, but I would love to do something like this:

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

Ideally, I wouldn't even need to reference the has again since it's what the case statement is about. If I only wanted to use one option then I would "case cool_hash[:that_option]", but I'd like to use any number of options. Also, I know case statements in Ruby only evaluate the first true conditional block, is there a way to override this to evaluate every block that's true unless there is a break?

like image 305
Michael K Madison Avatar asked Jun 26 '13 17:06

Michael K Madison


3 Answers

You could also use a lambda:

case cool_hash
when -> (h) { h[:key] == 'something' }
  puts 'something'
else
  puts 'something else'
end
like image 62
marknery Avatar answered Sep 20 '22 11:09

marknery


Your code is very close to being valid ruby code. Just remove the variable name on the first line, changing it to be:

case

However, there is no way to override the case statement to evaluate multiple blocks. I think what you want is to use if statements. Instead of a break, you use return to jump out of the method.

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
like image 45
David Grayson Avatar answered Sep 23 '22 11:09

David Grayson


I think, following is the better way to do the stuff you want.

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

Even in case's else part you can use 'case cool_hash[:crazy_option]' instead of 'if' if there are more conditions. I prefer you to use 'if' in this case because there is only one condition.

like image 40
Data Don Avatar answered Sep 21 '22 11:09

Data Don