【发布时间】:2020-02-09 11:55:36
【问题描述】:
以String#each_char 的 ruby API 文档解释为例,它表明在调用此方法和给定块时会收到一个字符串。
each_char {|cstr| block } → str
但是在 irb 中执行这个时,输出并不像预期的那样,只返回我们开始使用的字符串。
irb(main):001:0> v = "foobar".each_char { |c| c + "." }
=> "foobar"
这导致的问题是,分配这个方法调用非常具有欺骗性,因为它不会返回预期的结果,而只是我们开始使用的字符串:
irb(main):002:0> puts v
foobar
=> nil
使用break 指令是在变量赋值期间从块中返回值的唯一方法。
irb(main):003:0> v = "foobar".each_char { |c| break c + "." }
=> "f."
问题:
为什么用块调用的方法不返回它们计算的值?这只是这个实现的一个特例,因为我确信Array#each 确实返回了一个新数组。但话又说回来,String#each_byte 也没有返回任何东西。这是怎么回事?
从块中分配已处理值的最优雅方法是什么?猴子修补是一种选择吗?
附加信息: 我正在使用 ruby 2.6.3
(注意:我已经看到 [来自 Ed 的这个问题],但是虽然 2017 年的结论是使用赋值运算符会导致语法错误,但在 Array#each 的情况下,ruby 显然不会像这样。)
【问题讨论】:
-
嗯,
Array#each也返回self。您在寻找map/collect方法吗? -
虽然与实际问题无关,但你的例子可以用
'foobar'.gsub(/(?<=.)/m, '.') #=> "f.o.o.b.a.r."实现。 -
我建议您删除除“Ruby”之外的所有标签,因为不太可能有人会过滤任何其他标签,因为他们知道这样做会错过许多感兴趣的答案所以。例如,假设有人想查看使用
each的 Ruby 答案。可能有数千个带有“Ruby”标签的人这样做,但你的可能是唯一一个也有“每个”标签的人。 -
我并不是真的在寻找地图/收集或 gsub。我刚刚注意到您不能将在 Array#each_char 块中完成的突变分配给文档建议的变量。此处给出的示例并非真正旨在实现任何特定目标。
-
"为什么用块调用的方法不返回它们计算的值?" - 某些方法不止一次调用该块,例如
each。那么它们应该返回哪些值呢?
标签: ruby