如何将一个 Ruby 方法转换成块?

21

有没有一种方法可以简化以下代码?

filenames是一个包含文件名的列表(字符串),例如["foo.txt", "bar.c", "baz.yaml"]

filenames.map { |f| File.size(f) }
有没有办法将“File.size”转换为proc或块?对于现有对象的方法,我可以使用&:method。针对模块级别的方法是否有类似的东西?

有没有办法将"File.size"转换为Proc或block?对于现有对象的方法,我可以使用&:method。是否有类似模块级别方法的方法?

3个回答

33

是的,这就是我要给的那个..但你比我快了..感谢你的呈现.. +1 - Arup Rakshit
有趣的是,我本来会猜错'&'的绑定顺序。 - DGM

5
filesize = proc { |f| File.size(f) }
filenames.map(&filesize)

非常酷。为什么我没想过这样做?现在我有了一个很棒的新重构技巧。 - Mark Thomas
4
这并没有简化它,反而增加了额外的复杂性。 - Martin C. Martin
2
@MartinC.Martin 确实,它并没有简化它。但这正是你所要求的。这个答案非常简单地将表达式转换为了一个过程。怪只能怪你自己。这是你的错,而不是Logan的错。 - sawa
1
在这种情况下,它并没有简化它,但如果您需要重新使用该过程,则可以帮助保持DRY。有时,为复杂的过程命名(通过本地变量或方法)也有助于在您不关心过程的细节实现时保持代码可读性。 - Logan Serman
@MartinC.Martin 顺便说一下,这两者在一个重要的方面有微妙的不同。像这样使用.method返回的是一个lambda,而不仅仅是一个proc。尝试一下,你就会知道我的意思:%w{what a nice little doggo}.map(&String.new.method(:upcase)) - Alex Moore-Niemi

4

标准库中的Pathname提供了一种更面向对象的文件和目录处理方式。也许有一种方法可以重构你的filelist,例如,不要使用以下方式:

filenames = Dir.entries(".")
filenames.map { |f| File.size(f) }

您将使用:

require 'pathname'
filenames = Pathname.new(".").entries
filenames.map(&:size)

3
谢谢,这解决了我的实际问题,尽管它没有回答问题的标题。 - Martin C. Martin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接