【问题标题】:Assignment of a return-values of method blocks in ruby在 ruby​​ 中分配方法块的返回值
【发布时间】: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


【解决方案1】:

首先,#each 不会返回一个新数组。 each 意味着它会处理数组的每个元素,但最终会返回它的接收者。

要从块中打印某些内容,您需要使用 printputs

有几种方法可以分配每个的结果:

首先:使用#with_object

=> v = "foobar".each_char.with_object('') { |c, obj| obj << c + '.'  }
=> v
=> "f.o.o.b.a.r."

还有一个:使用#chars#join

=> v = "foobar".chars.join('.')
=> v
=> "f.o.o.b.a.r"

【讨论】:

  • 所以当#each 返回它的接收者时,#each_char (#each_byte) 返回什么点?这种不一致的回报背后的想法是什么?
  • @D.Asyl: each_chareach_byte 返回他们的接收者。 All each-like 方法总是返回它们的接收者。但实际上,由于each 的目的只是它的副作用,所以返回值甚至都无关紧要。
  • 我可以发誓,前几天我测试了.each 的工作,它确实返回了预期的数组。但它没有,所以我的坏。毕竟没有什么错。这就是解决方案。谢谢大家。
猜你喜欢
  • 2012-03-01
  • 1970-01-01
  • 2014-05-17
  • 1970-01-01
  • 1970-01-01
  • 2015-02-12
  • 1970-01-01
  • 2015-07-11
  • 2013-10-19
相关资源
最近更新 更多