if var.is_a?(…)

If an if‘s condition is an is_a? test, the type of a variable is guaranteed to be restricted by that type in the then branch.

  1. if a.is_a?(String)
  2. # here a is a String
  3. end
  4. if b.is_a?(Number)
  5. # here b is a Number
  6. end

Additionally, in the else branch the type of the variable is guaranteed to not be restricted by that type:

  1. a = some_condition ? 1 : "hello"
  2. # a : Int32 | String
  3. if a.is_a?(Number)
  4. # a : Int32
  5. else
  6. # a : String
  7. end

Note that you can use any type as an is_a? test, like abstract classes and modules.

The above also works if there are ands (&&) in the condition:

  1. if a.is_a?(String) && b.is_a?(Number)
  2. # here a is a String and b is a Number
  3. end

The above doesn’t work with instance variables or class variables. To work with these, first assign them to a variable:

  1. if @a.is_a?(String)
  2. # here @a is not guaranteed to be a String
  3. end
  4. a = @a
  5. if a.is_a?(String)
  6. # here a is guaranteed to be a String
  7. end
  8. # A bit shorter:
  9. if (a = @a).is_a?(String)
  10. # here a is guaranteed to be a String
  11. end