【问题标题】:Is there a shorthand for Ruby Blocks?Ruby Blocks 有简写吗?
【发布时间】:2016-08-08 20:57:47
【问题描述】:

我发现自己对以下用 Ruby 编写的冗长内容感到恼火:

polys.each { |poly| poly.edges.each {|edge| draw edge.start, edge.end } }

(polys是一个多边形数组,边是多边形返回边数组的一种方法)

理想情况下,我想把它缩短成这样:

polys.each.edges.each { draw _.start, _.end }

更具体地说,我想知道:

  • 我们如何编写一个method_missing hack,就像第一个一样? (在使用缺少的方法调用时,枚举器可以对从枚举返回的每个项目调用此方法)
  • 有没有办法使用任何符号或默认名称摆脱|x|

【问题讨论】:

  • 您想要做的事情在 Ruby(或任何脚本语言)中是有问题的,因为 Ruby 直到运行时才知道接收器的任何信息。比较 [[1,2],[3,4]].each { |e| puts e }[[1,2],[3,4]].each { |_,e| puts e } 这里如何使用块变量的默认值?
  • 作为一个 C 编码员很久以前,“冗长的写作”给我带来了微笑。虽然它并不短,但您可能会发现以明显的方式将您拥有的内容分成方法更清晰:def draw_edge(edge); draw edge.start, edge.end; end; def draw_poly(poly); poly.each { |edge| draw_edge(edge) }; end; def draw_polys(polys) { |poly| draw_poly(poly) }.
  • 要求提供功能 x 的 gem 是题外话,因此您应该将其从问题中删除。 “要求我们推荐或查找书籍、工具、软件库、教程或其他非现场资源的问题对于 Stack Overflow 来说是无关紧要的,因为它们往往会吸引固执己见的答案和垃圾邮件。相反,describe the problem 和已经完成的事情到目前为止解决它。”
  • 感谢您的评论(逗号已更正)。 @CarySwoveland:我要求一种语言功能,如果没有 |...| 则允许使用诸如 x 之类的名称用来。想一想:Perl 会怎么做?
  • 对不起,我不懂 Perl。

标签: ruby verbosity


【解决方案1】:

没有。你能做的最接近的是:

polys.flat_map(&:edges).each { |_| draw _.start, _.end }

flat_map 会将一个数组转换为另一个数组,并将其展平为一维数组。如果块内部正在调用没有参数的单个方法,您可以使用&:edges 快捷方式。

话虽如此,我可能会更接近您的初始提案,因为它更具可读性:

polys.each do |poly| 
  poly.edges.each {|edge| draw edge.start, edge.end }
end

请记住,您只编写一次代码,但阅读次数很多,因此可读性胜过简洁性。

【讨论】:

  • polys.flat_map(&:edges).each {|edge| draw(edge.start, edge.end) } 更好,不需要将 map 和 flatten 作为单独的方法。
  • 另外,如果他们定义了draw_edge 方法,他们可以只写polys.flat_map(&:edges).each(&method(:draw_edge))
猜你喜欢
  • 2011-03-30
  • 1970-01-01
  • 2011-03-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多