为什么Ruby中不能使用“if zero”?

10
>> current_user.first_visit
=> 0
>> if current_user.first_visit
>> puts "test"
>> end
test
=> nil
为什么会打印出test?

看起来你的问题已经得到了解答。但是如果你的编程语言支持,你应该停止使用数值来表示真/假,而应该使用关键词true和false。 - colithium
Rails已经扩展了整数类型。您还可以使用“if current_user.first_visit.zero?” - vise
1
@vise:.zero? 是普通的 Ruby 语法:APIdock.com 链接 - Andrew Grimm
这个问题可能是 有哪些 Ruby 坑点需要新手注意? 的重复。 - Andrew Grimm
3个回答

16
在Ruby中,只有nil可以被看作是与false类似的东西。不能假设0""[]代表false,因此必须使用== 0.blank?.empty?.zero?等方法。
但是,nil并不总是像false一样运作。例如,在字符串内插时,会对#{}的内容应用.to_s方法,这在FalseClassNilClass上的处理方式是不同的:
irb(main)> "qwe #{false} rty"
=> "qwe false rty"
irb(main)> "qwe #{nil} rty"
=> "qwe  rty"

1
请注意,.blank?.empty?是Rails框架(通过activesupport提供)提供的扩展,不可用于Ruby标准或核心库中。 另外,不同的行为是因为"#{false}"调用了to_s方法。 - Swanand
2
@swanand: zero?empty? 存在于核心库中(不过我不确定你所想的是哪些类)。 - Mladen Jablanović
@pdom的编辑是正确的。我不知道为什么其他人拒绝了它。http://stackoverflow.com/review/suggested-edits/7845176 - Nakilon

6
你可以将 Ruby 的 if 看作是测试布尔值或数据的可用性(而不是 nil)。C 语言中支持将 0 隐式转换为 false,这更多是历史遗留问题,因为在 C 还没有明确的布尔类型时,0 是一个方便的哨兵值或具有直观意义的值。然而,在许多情况下(例如在一些国家,衣服尺码从 0 到 8,POSIX libC 函数调用结果等),零不能很好地转换成逻辑上等价的布尔值,因此 Ruby 走自己的路线也无可厚非。
从这个角度来看,你的代码存在问题,因为 current_user.first_visit - 其名称暗示它是布尔类型 - 实际上保存了 0 而不是 false。或者,如果你有一个明显的数字 current_user.visit_counter,那么使用以下语句之一是自然和正确的:
current_user.visit_counter > 0
current_user.visit_counter >= 1
current_user.visit_counter != 0

我认为这非常不方便,特别是当你来自其他编程语言时,0几乎总是被视为假值,这使得在Ruby中的工作更加困难。 - Vedmant

1
你可以试试这个。
>> current_user.first_visit
=> 0
>> if current_user.first_visit != 0
>> puts "test"
>> else
>> puts "fail"
>> end
fail
=>nil

在检查数字值时,您还需要将其与预期值匹配


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接