Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Return command in Ruby Switch?

I would like to return a value from my Case statement and I need to execute more than a single line of code so "then" doesn't work for me. Using Return exits the function that the Case statement is in. Is there a keyword that will help my code clearly imply what I am returning without just putting a value on the last line?

complexity = case(scale)
  when "gtp"
     x = [various lines of code]
     x = [various lines of code]
     10
  when "preSi"
     x = [various lines of code]
     x = [various lines of code]
     30
  when "postSi"    
     x = [various lines of code]
     x = [various lines of code]
     40
  else
     error"Scale not recognized: #{scale.to_s}"
  end
like image 997
Mike Carpenter Avatar asked Jan 29 '26 23:01

Mike Carpenter


2 Answers

Depending on what happens in various lines of code, you could refactor it into several methods:

complexity = case(scale)
  when 'gtp'   then gtp_complexity
  when 'preSi' then preSi_complexity
  ...
end

# and elsewhere...
def gtp_complexity
  x = [various lines of code]
  x = [various lines of code]
  10
end
...

Of course, once you have this you can ditch the case in favor of a Hash of lambdas:

complexities = {
  'gtp' => lambda { ... },
  ...
}
complexities.default_proc = lambda do |h, scale|
  lambda { error "Scale not recognized: #{scale}" }
end

complexity = complexities[scale].call

Or if you like the methods better, use a Hash of methods:

complexities = {
  'gtp' => method(:gtp_complexity),
  ...
}
complexities.default_proc = lambda do |h, scale|
  lambda { error "Scale not recognized: #{scale}" }
end

complexity = complexities[scale].call

or use the instance itself as your lookup table and whitelist:

complexity = if(respond_to?("#{scale}_complexity"))
  send("#{scale}_complexity")
else
  error "Scale not recognized: #{scale}"
end
like image 50
mu is too short Avatar answered Jan 31 '26 11:01

mu is too short


No there is not a keyword to explicitly label the returned value from a case statement in Ruby.

You can explicitly assign to the variable, you are already doing that with x, and presumably using that local variable further down, it's no different:

  case(scale)
  when "gtp"
     x = [various lines of code]
     x = [various lines of code]
     complexity = 10
  when "preSi"
     x = [various lines of code]
     x = [various lines of code]
     complexity = 30
  when "postSi"    
     x = [various lines of code]
     x = [various lines of code]
     complexity = 40
  else
     error "Scale not recognized: #{scale.to_s}"
  end

If that doesn't work for you, then other constructs are available that might avoid using case at all, or you could move your multi-line constructs into other methods or even a class that holds x and complexity. Whether or not this could improve your code is more a subject for https://codereview.stackexchange.com/ - it will depend on higher level things, such as whether your scale categories appear elsewhere.

like image 25
Neil Slater Avatar answered Jan 31 '26 13:01

Neil Slater



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!