在采用布尔参数的环境中,包装所有函数而不是允许它们被隐式强制是一个好主意吗?

时间:2011-09-12 11:18:25

标签: ruby truthiness

String#=~函数为例。如果找到匹配,它将返回第一个匹配的索引,因为Fixnum在布尔环境中将始终作为true。如果未找到匹配项,则返回null,该行为为false。

现在假设我有一个班级:

class A
  attr_accessor :myprop

  # prints "I am awesome" if #myprop matches /awesome/
  # and "I am not awesome" otherwise
  def report_on_awesomeness!
    puts "I am #{myprop =~ /awesome/ ? 'awesome' : 'not awesome'}."
  end
end

此代码几乎可以按预期工作,但试用条件运算符中的第一个元素是我的问题的主题。

不包裹myprop =~ /awesome/是个好主意吗?我不是在谈论将它抽象为另一种方法,如def is_awesome?; myprop =~ /awesome/; end,而是我的当前约定是否强制Ruby将Fixnums隐式地转换为true而nils为false,这比将条件包装成我自己投射的内容更可取。我可以轻松地做到这一点:

class A
  attr_accessor :myprop

  # prints "I am awesome" if #myprop matches /awesome/
  # and "I am not awesome" otherwise
  def report_on_awesomeness!
    puts "I am #{(myprop =~ /awesome/).nil? ? 'not awesome' : 'awesome'}."
  end
end

我看到第一种风格的优点:

  • 大多数维护者(包括未来的我)都习惯于隐式
  • 它更短

优点我看到第二种风格:

  • 更明显的是=~方法的结果与其布尔解释之间的关系究竟是什么
  • 它让您可以更自由地使用更具创意的显式投射

我怀疑可能存在一些中间立场,在其中它是惯用的情况下会留下隐式类型转换(例如,使用=~进行正则表达式匹配)并且当它不是时(例如,您自己的属性)明确地执行它,特别是如果它们有多种返回类型)。

我希望社群可以就此问题分享任何见解或经验。

1 个答案:

答案 0 :(得分:0)

恕我直言,这是个人选择。你可以采取任何风格,因为你通过这种方式感觉更好。

我在true?上定义Object以获取其布尔值(另一个名称可能是to_bool):

class Object
  def true?
    !!self
  end
end

但是double bang (!!)更容易将任何东西转换为布尔值,我更喜欢使用它 - 但不是无处不在。我只在需要明确的布尔值时使用它(在这个问题的情况下我不会使用它)。

BTW,false.nil? == false;它可能导致混乱。