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
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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With