ruby - 为什么 Ruby 有 TrueClass 和 FalseClass 而不是单一的 Boolean 类?

标签 ruby language-design

当发现这个时,我正在研究序列化值。 Ruby 有一个 TrueClass类,和一个 FalseClass类,但它没有 Boolean 类。我想知道这是为什么。

我发现使用 Boolean 有一些优势;例如,字符串解析可以集中在它上面。

Ruby 开发人员比我聪明,所以一定有很多我看不到的充分理由。但现在在我看来它像有 OneClassTwoClass 而不是 Fixnum .

最佳答案

类的目的是将相似的对象或具有相似行为的对象组合在一起。 12 非常相似,因此将它们放在同一个类中是完全合理的。 truefalse 然而相似。事实上,它们的重点是它们恰好是彼此的对立并且具有相反的行为。因此,它们不属于同一类。

您能否举例说明您将在 Boolean 类中实现哪种常见行为?我想不出任何东西。

让我们看看 TrueClassFalseClass 的行为:那里正好有 四个 方法。不再。在每种情况下,这两种方法的作用完全相反。您如何以及为什么将它放在一个类中?

以下是您如何实现所有这些方法:

class TrueClass
  def &(other)
    other
  end

  def |(_)
    self
  end

  def ^(other)
    !other
  end

  def to_s
    'true'
  end
end

现在反过来:

class FalseClass
  def &(_)
    self
  end

  def |(other)
    other
  end

  def ^(other)
    other
  end

  def to_s
    'false'
  end
end

诚然,在 Ruby 中,有很多在幕后发生的“魔法”,它们实际上并不是由 TrueClassFalseClass 处理的,而是硬连线的进入解释器。诸如 if&&||! 之类的东西。然而,在 Smalltalk 中,Ruby 借鉴了很多东西,包括 FalseClassTrueClass 的概念,所有这些也都是作为方法实现的,你可以做同样的事情在 ruby 中:

class TrueClass
  def if
    yield
  end

  def ifelse(then_branch=->{}, _=nil)
    then_branch.()
  end

  def unless
  end

  def unlesselse(_=nil, else_branch=->{})
    ifelse(else_branch, _)
  end

  def and
    yield
  end

  def or
    self
  end

  def not
    false
  end
end

反之亦然:

class FalseClass
  def if
  end

  def ifelse(_=nil, else_branch=->{})
    else_branch.()
  end

  def unless
    yield
  end

  def unlesselse(unless_branch=->{}, _=nil)
    ifelse(_, unless_branch)
  end

  def and
    self
  end

  def or
    yield
  end

  def not
    true
  end
end

几年前,我写上面的内容只是为了好玩和 even published it .除了由于 Ruby 使用特殊运算符而我只使用方法导致语法看起来不同之外,它的行为与 Ruby 的内置运算符完全一样。其实我其实是拿了the RubySpec conformance testsuiteported it over to my syntax它通过了。

关于ruby - 为什么 Ruby 有 TrueClass 和 FalseClass 而不是单一的 Boolean 类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3192978/

相关文章:

ruby - 如何使用 new 干净地初始化 Ruby 中的属性?

arrays - 如何将带有 'array' 键的 ruby​​ 哈希转换为 Ruby 中的嵌套哈希?

ruby-on-rails - has_one owns_to 关联属性验证

scala - 为什么 Scala 的库在 2.7 和 2.8 之间增加了一倍?

programming-languages - 执行类型推断的代码

compiler-construction - 变体转换系统

c++ - 是否有必须使用 `is_detected_v` 的典型用例?

arrays - Array#push 导致大数组出现 "stack level too deep"错误

r - ->(右箭头)和 <-(左箭头)在 for 循环中的不同行为

ruby-on-rails - 如何抑制 Rails 控制台/irb 输出