在查看这些表达式的行为后:
1 and 0 #=> 0
0 and 1 #=> 1
1 and true #=> true
0 and true #=> true
对我来说,无论逻辑表达式的评估结果如何,更像是ruby返回逻辑门的右侧值。我正在寻找它的原因。
答案 0 :(得分:3)
您需要了解的两件事情:
and
(和&&
)返回第一个操作数(如果为false),否则返回第二个操作数。false
和nil
以外的任何内容均为真,包括0
。答案 1 :(得分:1)
Ruby表现得很好,但如果你来自另一种语言,可能会让人感到困惑。这种混淆最常由以下原因引起:
and
之类的流量控制运算符来测试相等而不是==
。要解决您描述的问题,请使用相等运算符来测试真实性。以下是更详细的解释。
在Ruby中,每个表达式都返回一个值。当您评估表达式时:
1 and 0 #=> 0
您没有像使用实际的布尔返回表达式那样检查每个表达式的真实性,例如:
!!(1 and 0) #=> true
相反,您只是按顺序评估两个表达式,除非第一个表达式的计算结果为 nil 或 false 并将评估短路。无论哪种方式,Ruby都会返回最后一个表达式的值。在这种情况下,您可以使用以下结果获得相同的结果:
1; 0 #=> 0
使用Ruby标准库,您可以看到解析器看到的内容。例如:
require 'pp'
require 'ripper'
pp Ripper.sexp '1 and 0'
#=> [:program, [[:binary, [:@int, "1", [1, 0]], :and, [:@int, "0", [1, 6]]]]]
使用ruby_parser gem代替Ripper时,S-expression可能更清晰,更易于阅读。例如:
require 'pp'
require 'ruby_parser'
pp RubyParser.new.parse '1 and 0'
#=> s(:and, s(:lit, 1), s(:lit, 0))
无论哪种方式,由于第一个表达式1
计算为整数文字(例如 nil 或 false 以外的其他文字),0
是然后评估。第二个Integer文本也计算为true,因此整个表达式为true(在此上下文中无关)并返回0,因为0
是最后一个表达式。
在Ruby中,all values other than nil or false are true。您通常希望将表达式与诸如and之类的相等运算符进行比较,或者将表达式强制转换为具有!!
的布尔上下文,而不是==运算符。例如:
# Evaluate equality and return a Boolean result.
1 == 1 #=> true
0 == 1 #=> false
# Evaluate whether an expression is equal to true. In this case,
# the double-negation of `!!` casts each Integer as a Boolean value.
!!1 == true #=> true
!!0 == true #=> true
# Use `and` flow-control operator to evaluate right-hand expression
# if the left-hand side evaluates as truthy.
(1) and (true) #=> true
(1) and (false) #=> false