34

我有一个布尔值来检查它是否为真,然后设置一个局部变量。我如何重构它以使其更像 Ruby?

if firm.inflection_point
  inflection_point = 1
else
  inflection_point = 0
end
4

8 回答 8

70
inflection_point = (firm.inflection_point ? 1 : 0)
于 2012-11-24T00:47:48.253 回答
24

另一种选择是使用短路运算符:

inflection_point && 1 || 0


irb(main):001:0> true && 1 || 0
=> 1
irb(main):002:0> false && 1 || 0
=> 0
于 2017-01-18T01:26:11.307 回答
21

如果您只是在某一点上拥有它,那么rudolph9 的答案很好,但是如果您到处都有类似的逻辑,那么考虑到猴子补丁的一般用途可能是有意义的:

class FalseClass; def to_i; 0 end end
class TrueClass; def to_i; 1 end end

inflection_point = firm.inflection_point.to_i

在 Ruby 中,您应该让所有逻辑都处理真值而不是0and 1,但我猜您正在处理来自/到某些处理0and的外部系统的一些输入或输出1。然后,这样做将是有意义的。

于 2012-11-24T04:29:35.553 回答
7

在 Ruby 中,if是一个表达式。无需在thenandelse分支内分配变量,只需返回所需的值并将变量分配给if expression:

inflection_point = if firm.inflection_point
  1
else
  0
end

在像这样的简单情况下,将整个表达式写在一行上更具可读性:

inflection_point = if firm.inflection_point then 1 else 0 end

您还可以使用条件运算符,我个人认为它的可读性要差得多:

inflection_point = firm.inflection_point ? 1 : 0
于 2012-11-24T13:40:14.947 回答
4

您需要的是一种称为三元运算符的条件运算,它几乎用于每种语言,并且使用符号?和 :

inflection_point = firm.inflection_point ? 1 : 0

基本上意味着,如果第一个条件评估为真(firm.inflection_point),则返回“?”之后的值 (1) 否则返回“:”后面的值 (0)

于 2012-11-24T05:34:35.797 回答
2

它不是纯红宝石解决方案,但是,您可以使用ActiveRecord::Type::Integer.new.cast(true)

于 2019-02-21T08:50:40.603 回答
2

我刚刚注意到很多人建议 Monkey Patch ruby​​ 类并.to_i在它们上实现方法以解决这个问题。

我需要温和地告知猴子修补TrueClass行为FalseClass 可能对您的系统造成危险

一个好的方法是使用Ruby Refinements来进行更安全的猴子补丁。这种方法将猴子修补类的更改限制在您的类范围内。

  • lib/refinements/boolean_refinements.rb
module BooleanRefinements
  refine FalseClass do
    def to_i
      0
    end
  end

  refine TrueClass do
    def to_i
      1
    end
  end
end
  • /your_class.rb
require 'refinements/boolean_refinements'

class MyClass
  using BooleanRefinements

  # Here you can use true.to_i and false.to_i as you wish
end
于 2020-12-28T06:13:05.723 回答
1

这是另一种方法:

5 - bool.to_s.length

这利用了'true'有四个字符而'false'有 5 个字符的事实。

于 2017-01-20T21:06:48.340 回答