Search code examples
rubyconditional-statementscaseor-operatorandand

Using ruby's 'case'/'when' method with || or && operators, etc


I just tried to run some code that looked like this

def get_proj4(srid, type=nil)
  type.downcase! if type
  case type
  when nil || "epsg"
   open("http://spatialreference.org/ref/epsg/#{srid}/proj4/").read
  when "esri"
   open("http://spatialreference.org/ref/esri/#{srid}/proj4/").read
  end
end

and it didn't run properly, returning nil every time. wrapping the nil || "epsg" in parentheses didn't work either

It turns out ruby wouldn't allow me to use the || operator in this

Now I assume ruby takes the case/when method and ultimately breaks it down into a group of conditionals looking something like

x = type
  if x == (nil || "epsg")
    y = ...runs code...
  elsif x == "esri"
    y = ...
  end
x = nil
y

but obviously it does not. What's going on here?

Thanks


Solution

  • The expression is evaluated first so when nil || "espg" is equivalent to when "espg"1 - it will never match nil.

    To match either-or, separate the options with a comma:

    case type
    when nil, "espg" ..
    when "esri" ..
    

    Or, alternatively, perhaps normalize the value:

    case (type || "espg")
    when "espg" ..
    when "esri" ..
    

    Or use the other form that resembles an if-else:

    case
    when type.nil? || type == "espg" ..
    when type == "esri" ..
    

    Or some combination of everything :)


    1 This is also the same reason why the example if is suspect. It should probably be written like:

    if type.nil? || type == "espg"