除非.blank之间的问题?而如果

时间:2011-12-22 20:28:50

标签: ruby-on-rails

请查看以下代码段。 请注意,@product.name为空。

代码A

<% if @product.name %>
  <div class="bonus">
    <h4>Bonus</h4>
    <%= @product.name %>                
  </div>
<% end %>   


代码B

<% unless @product.name.blank? %>
  <div class="bonus">
    <h4>Bonus</h4>
    <%= @product.name %>                
  </div>
<% end %>   


根据我对如何使用ifunless的理解(感谢this文章),代码A和B 都应该有完全相同的功能,但代码A 是根据最佳实践执行此操作的正确方法。

问题是,代码A 显示会生成<h4>Bonus</h4>标记,而代码B 则不会生成{{1}}标记。

这怎么可能?

5 个答案:

答案 0 :(得分:4)

那是因为在Ruby中,空字符串是 true

只有falsenil评估为false,Ruby中的所有其他内容都为真,包括空字符串(与Perl或PHP等语言不同)。

这就是为什么Rails引入blank?(后来与present?相反)

来自Rails的源代码:

# An object is blank if it's false, empty, or a whitespace string.
# For example, "", "   ", +nil+, [], and {} are all blank.
#
# This simplifies:
#
#   if address.nil? || address.empty?
#
# ...to:
#
#   if address.blank?
def blank?
  respond_to?(:empty?) ? empty? : !self
end

# An object is present if it's not <tt>blank?</tt>.
def present?
  !blank?
end

答案 1 :(得分:3)

他们不一样。

  • blank?检查nil和空格。
  • if检查真实性。只有空格的字符串,包括空字符串,是真的。

等效的if语句为if @product.name.present?

答案 2 :(得分:2)

unless X.blank? if X相反!

@product.name除非设置为falsenil,否则无效。如果它包含空字符串,程序流仍将进入if块,<%= @product.name %>将输出一个空字符串。

.blank?适用于字符串或仅包含空格的字符串。

答案 3 :(得分:2)

在Ruby中,只有nilfalse被视为错误值。因此,如果if语句中的条件不是nilfalse,则将执行内部代码。在您的示例中,A @product.name是空字符串,被Ruby视为真值。所以代码就会执行。

另一方面,Rails引入了blank?方法。它返回false:

  • nil
  • false
  • ''(空字符串)
  • ' '(whitespaced String)
  • {}(空哈希)
  • [](空数组)

这就是为什么你从false获得空blank?的{​​{1}}。

blank?相反的是present?方法。

答案 4 :(得分:0)

puts 'Empty string is truthy' if ''
#=> Empty string is truthy

那说,你可以这样做:

<% if @product.name? %>
<% if @product.name.present? %>
<% unless @product.name.blank? %>

最后带一个问号。这意味着“如果@ product.name存在”(&lt; =&gt;不是空白)

我的偏好是第一个(@product.name?