Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does Dir.glob("*.txt").sort also need .each?

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.)

like image 222
Camille Goudeseune Avatar asked Dec 20 '16 17:12

Camille Goudeseune


1 Answers

The second one fails because sort {|f| p f} really doesn't make sense. The block you use with sort is supposed to "return -1, 0, or +1" and take two arguments (the elements to be compared) but your block takes one argument and returns that argument because p str returns str.

The third one is fine because sort's default comparator block is equivalent to saying:

sort { |a, b| a <=> b }

so .sort.each makes perfect sense.

If you use the sort of block that sort expects in the second example:

Dir.glob("*.txt").sort {|a, b| a <=> b }

then things will work better. Or you could just leave out the block if you want to sorting things in ascending lexical order:

Dir.glob('*.txt').sort
like image 165
mu is too short Avatar answered Oct 05 '22 20:10

mu is too short