我有一个布尔值来检查它是否为真,然后设置一个局部变量。我如何重构这个更多Ruby-ish?
if firm.inflection_point
inflection_point = 1
else
inflection_point = 0
end
答案 0 :(得分:59)
inflection_point = (firm.inflection_point ? 1 : 0)
答案 1 :(得分:16)
如果你只是在某一点上,那么rudolph9's answer是好的,但是如果你在整个地方都有类似的逻辑,那么也许它可能是有意义的一般用途的猴子补丁:
class FalseClass; def to_i; 0 end end
class TrueClass; def to_i; 1 end end
inflection_point = firm.inflection_point.to_i
在Ruby中,你应该保持所有的逻辑处理真值而不是0
和1
,但我想你正在处理来自某些外部系统的一些输入或输出使用0
和1
。然后,这样做会有意义。
答案 2 :(得分:11)
另一种选择是使用短路运算符:
inflection_point && 1 || 0
irb(main):001:0> true && 1 || 0
=> 1
irb(main):002:0> false && 1 || 0
=> 0
答案 3 :(得分:6)
在Ruby中,if
是一个表达式。无需在then
和else
分支内分配变量,只需返回所需的值并将变量分配给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
答案 4 :(得分:4)
您需要的是一个称为三元运算符的条件运算 它几乎用在所有语言中并使用符号?并且:
inflection_point = firm.inflection_point ? 1 : 0
基本上意味着,如果第一个条件的计算结果为true(firm.inflection_point),则返回“?”之后的值。 (1)否则,返回“:”(0)
之后的值答案 5 :(得分:1)
这是另一种方法:
5 - bool.to_s.length
这利用了'true'
有四个字符,而'false'
有5个字符的事实。
答案 6 :(得分:0)
这不是纯红宝石解决方案,但是,您可以使用ActiveRecord::Type::Integer.new.cast(true)
答案 7 :(得分:0)
我刚刚注意到很多人提出给 Monkey Patch ruby 类并在它们上实现 .to_i
方法以解决这个问题。
我需要轻轻地通知 Monkey Patching 的行为 TrueClass
和 FalseClass
can be dangerous to your system
一个好的方法是使用 Ruby Refinements 来进行更安全的猴子补丁。这种方法将monkey patched 类的更改限制在您的类的范围内。
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