Why `case/when` does NOT work with just result codes?
Sometimes it may feel idiomatic to check the result code in the following way:
# wrong
if result.not_success?
case result.code # `result.code` returns fancy object
when :full_queue
notify_devops
when :duplicated_job
notify_devs
else
# ...
end
end
Although this snippet looks very appealing, it won't work as expected.
A lot of Ruby folks often have an assumption that a value of case
is compared with a value of when
.
case value === when value
In other words, the case/when
from example above can be transformed to if/else
like so:
# wrong
if result.not_success?
if result.code === :full_queue
notify_devops
elsif result.code === :duplicated_job
notify_devs
else
# ...
end
end
But, that is NOT correct.
In reality, the value of when
is always compared with the value of case
.
when value === case value
Let's write the proper transformation:
# okish
if result.not_success?
if :full_queue === result.code
notify_devops
elsif :duplicated_job === result.code
notify_devs
else
# ...
end
end
Symbol#=== is just an alias to Symbol#==.
There is no way to hook into any behavior like with strings (String#=== calls to_str on its argument).
As a result, just case result.code
is not enough.
But once you use case result.code.to_sym
, the natural Ruby charm is back.
# ok
if result.not_success?
case result.code.to_sym
when :full_queue
notify_devops
when :duplicated_job
notify_devs
else
# ...
end
end