Dir.glob("*.txt") {|f| p f}
打印文件名。
Dir.glob("*.txt").sort {|f| p f}
因ArgumentError而失败。
Dir.glob("*.txt").sort.each {|f| p f}
按字母顺序打印文件名。
为什么第二个失败?更好的是,为什么第一个工作,有或没有.each
?
Dir.glob
和Dir.glob.sort
都是数组。Dir.glob.methods == Dir.glob.sort.methods
。(灵感来自Alphabetize results of Dir.glob。不是Dir.glob with sort issue的副本,因为“第三个”已经回答了那个人的问题。)
另一个答案是正确的,但我认为有更深刻的解释。当你在方法调用之后有一个块时,比如Dir.glob("*.txt") {|f| p f}
,该块是该方法的(可选)参数。在Dir.glob
的定义中,有一个运行块的yield
语句。
当您链接方法时,例如在Dir.glob("*.txt").sort {|f| p f}
中,块变为sort
方法的参数而不是glob
方法。 sort
也可以用一个块来定义比较,但是这个块在这种情况下没有意义。
链接each
得到Dir.glob("*.txt").sort.each {|f| p f}
使得块成为each
方法的参数,它使用它像glob
一样(为每个参数运行块)。
第二个失败,因为sort {|f| p f}
真的没有意义。与sort
一起使用的块应该是"return -1, 0, or +1"并且接受两个参数(要比较的元素),但是你的块接受一个参数并返回该参数,因为p str
返回str
。
第三个很好,因为sort
的默认比较器块相当于说:
sort { |a, b| a <=> b }
所以.sort.each
非常有意义。
如果您在第二个示例中使用sort
期望的那种块:
Dir.glob("*.txt").sort {|a, b| a <=> b }
事情会更好。或者,如果您想按升序词汇顺序对事物进行排序,则可以省略该块:
Dir.glob('*.txt').sort