【问题标题】:Ruby TrueClass single pipeRuby TrueClass 单管
【发布时间】:2014-12-26 15:17:37
【问题描述】:

来自文档:http://ruby-doc.org/core-2.2.0/TrueClass.html#method-i-7C

true |  puts("or")
true || puts("logical or")

# produces:

or
  • 您能否解释一下“单管”何时有用?
  • 有什么区别?

(仅在TrueClass 上下文中(不是ArrayFixnum 上下文)

【问题讨论】:

  • true || puts("logical or") 会给你true

标签: ruby


【解决方案1】:

当您不需要急切地评估 or 语句时,它很有用。

例如,如果你有一些方法,它们做一些有用的事情并返回 true/false 作为结果,并且有另一个方法应该只在这些方法中的任何一个返回 true 时才被调用,它是有用|:

def action1
  # do something, returns true/false
end

def action2
  # do something, returns true/false
end

def result_action
  # do something 
end

result_action if action1 | action2

如果您使用逻辑 || 而不是 action1 返回 true,则不会调用 action2(尽管会调用 result_action

【讨论】:

  • 当然。 puts 总是返回nil,所以a || b 的两边都在你的代码@Mugur'Bud'Chirica 中被调用
【解决方案2】:

很难说为什么TrueClass 定义了#| method

它是一个方法的事实确实意味着它的两个“操作数”都被评估然后组合,这就是输出字符串"or"的原因。双管道是一种特殊的结构:如果第一个操作数为真,它不会计算第二个操作数。因此,作为一种进行布尔计算的方法,单管道看起来毫无用处。

现在,Fixnum 上的运算符更有意义:它执行与 C、Java 等中相同的按位 OR。

例如:

>> 133|243
=> 247

现在,出于某种原因,Java 将布尔值上的 | 重载为非短路运算符。也许 Ruby 正在做“我也是”? Ruby 似乎不太可能在这里复制 Java。

更有可能是因为

true | e

评估为

e

对于任何 e,Ruby 允许您将一堆真实的表达式链接在一起。也许

true | e1 | e2 | e3 | e4

看起来比

e1
e2
e3
e4
true

甚至

e1; e2; e3; e4; true

另一种可能性是它允许您将产生布尔值的表达式与副作用链接在一起。

f(x1) | f(x2) | f(x3) | f(x4)

并返回是否有任何函数产生true。这是一个人为的例子:

>> def f(x);puts x;return x==2;end
=> :f
>> f(1) || f(2) || f(3) || f(4)
1
2
=> true
>> f(1) | f(2) | f(3) | f(4)
1
2
3
4
=> true

当然,这仍然只是一个蹩脚的尝试,因为你得到了同样的效果:

>> [f(1),f(2),f(3),f(4)].any?
1
2
3
4
=> true

我怀疑,但不是 100% 肯定,包含该运算符是为了代数意义上的某种“完整性”。布尔代数具有 AND 或 OR,而 || 并不是具有热切求值语义的经典意义上的真正方法。所以也许它是因为这个原因而被扔进去的,而且,如果任何程序员碰巧找到了它的用途,那就太好了。但在多年的编程中,我从未见过任何不短路的实用理由。

事实上,我认为如果有人编写的代码依赖在布尔上下文中对第二个参数的评估(即,使用#|),那么这样的代码会令人困惑--- 而且肯定不是引用透明的,因为它会依赖副作用 --- 因此应该重写。

【讨论】:

  • 大部分#|是一个方法,但||是一个操作符。
  • 谢谢。但是为什么不写:true && e1 && e2 && e3 && e4
  • 你知道,这是一个真的好问题。我仍在尝试自己弄清楚。当我想出一些东西时,我会把它添加到答案中。有很多方法可以做事。我怀疑你可以在某处的 DSL 中使用它,以某种方式,因为,正如你所怀疑的,它作为布尔运算符似乎完全没用!
  • 我试过的这个例子a |= puts 'hi' ; puts a ; #=> hi false 杀了我。在哪里有用,我仍然无法想象;)感谢您的回答。我投票赞成:)
  • 刚刚注意到stackoverflow.com/questions/9264897/…,但我认为这些案例有点复杂,应该重写。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-28
  • 2011-04-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多