在 case 语句与 if 语句中比较 类 时出现意外结果

Unexpected results when comparing classes in case statement vs an if statment

所以我正在编写一个模块函数来将 'falsey' 和 'truthy' 值转换为 true 和 false。为此,我使用了一个 case 表达式,据我所知,它基本上只是 a big elseif statement that uses the === function with the === operator being meant to be used for comparing sets. From the Ruby documentation the only difference I can really find between == and === is that === can be overwritten for comparing decedents of classes. I also understand that everything is a method call in ruby,所以我们不能假设 equality/subsumption 方法是可交换的。

当使用 case 语句按 class 排序时,我猜想 == 和 === 的功能是相同的,但我发现按 class 排序时它们case 语句从未将我的输入放入正确的 'bin'。那时我切换到使用 == 并且它确实有效所以我想知道为什么会这样,因为我正在比较 classes 我认为实际上是 "apples to apples" 比较。

module FirstTry
  def self.to_boolean(uncertain_value, to_integer: false)
    case uncertain_value.class
    when String
      value = ActiveRecord::Type::Boolean.new.cast(uncertain_value)
      return 1 if to_integer == true && value == true
      return 0 if to_integer == true && value == false
      return boolean_value
    when TrueClass
      return 1 if to_integer == true
      return true
    when FalseClass
      return 0 if to_integer == true
      return false
    when NilClass
      return 0 if to_integer == true
      return false
    end
    # I did not originally include this part of the code in the question
    raise 'Conversion Failed: No rules for converting that type of input into a boolean.'
  end
end

module SecondTry
  def self.to_boolean(uncertain_value, to_integer: false)
    if uncertain_value.class == String
      boolean_value = ActiveRecord::Type::Boolean.new.cast(uncertain_value)
      return 1 if to_integer == true && boolean_value == true
      return 0 if to_integer == true && boolean_value == false
      return boolean_value
    elsif uncertain_value.class == TrueClass
      return 1 if to_integer == true
      return true
    elsif uncertain_value.class == FalseClass
      return 0 if to_integer == true
      return false
    elsif uncertain_value.class == NilClass
      return 0 if to_integer == true
      return false
    end
    # I did not originally include this part of the code in the question
    raise 'Conversion Failed: No rules for converting that type of input into a boolean.'
  end
end

三等号 === 在 Ruby 的 case 表达式中被调用。我们发现能够表达如下内容很方便:

case object
when String
  "object is an instance of String!"
when Enumerable
  "wow, object is actually a bunch of objects!"
end

当然,这很方便,除非您实际持有 class,而不是 class 的实例。但是在您的示例中,您在 case 表达式中的对象上调用了 #class 。只需挂断电话,您的箱子就会被放入正确的箱子中。 :)