Dir.glob("*.txt") {|f| p f}
prints filenames.
Dir.glob("*.txt").sort {|f| p f}
fails with an ArgumentError.
Dir.glob("*.txt").sort.each {|f| p f}
prints filenames in alphabetical order.
Why does the second one fail? Better yet, why does the first one work, with or without the .each
?
Dir.glob
and Dir.glob.sort
are both Arrays.Dir.glob.methods == Dir.glob.sort.methods
.(Inspired by Alphabetize results of Dir.glob. Not a duplicate of Dir.glob with sort issue because the "third one" already answers that one's question.)
The other answer is correct, but I think there is a deeper explanation. When you have a block after a method call, like Dir.glob("*.txt") {|f| p f}
, the block is an (optional) argument to the method. In the definition of Dir.glob
, there is a yield
statement that runs the block.
When you chain the methods, like in Dir.glob("*.txt").sort {|f| p f}
, the block becomes an argument to the sort
method instead of the glob
method. sort
can also take a block to define a comparison, but this block doesn't make sense in that context.
Chaining each
to get Dir.glob("*.txt").sort.each {|f| p f}
makes the block an argument to the each
method, which uses it like glob
does (running the block for each argument).