请查看以下代码段。 请注意,@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 %>
根据我对如何使用if
和unless
的理解(感谢this文章),代码A和B 都应该有完全相同的功能,但代码A 是根据最佳实践执行此操作的正确方法。
问题是,代码A 显示会生成<h4>Bonus</h4>
标记,而代码B 则不会生成{{1}}标记。
这怎么可能?
答案 0 :(得分:4)
那是因为在Ruby中,空字符串是 true 。
只有false
和nil
评估为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
除非设置为false
或nil
,否则无效。如果它包含空字符串,程序流仍将进入if
块,<%= @product.name %>
将输出一个空字符串。
.blank?
适用于空字符串或仅包含空格的字符串。
答案 3 :(得分:2)
在Ruby中,只有nil
和false
被视为错误值。因此,如果if语句中的条件不是nil
或false
,则将执行内部代码。在您的示例中,A @product.name
是空字符串,被Ruby视为真值。所以代码就会执行。
另一方面,Rails引入了blank?
方法。它返回false:
nil
false
''
(空字符串)' '
(whitespaced String){}
(空哈希)[]
(空数组)这就是为什么你从false
获得空blank?
的{{1}}。
答案 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?
)