I am learning Ruby for the first time and I found that inside of a block statement when using the combined comparison operator (or spaceship operator) that a statement placed before the operator will run but a statement placed afterward will cause an error. I discovered this by playing with semicolons.
list.sort { |item1, item2| puts "foo"; item1 <=> item2 }
works but
list.sort { |item1, item2| item1 <=> item2; puts "foo" }
fails.
I tried this outside of a block statement and the problem goes away. I then tried on multi-line block statements like
list.sort do |item1, item2|
item1 <=> item2
puts "foo"
end
and it has the same problem as the single line block.
Does anyone know what is going on?
The best explanation I have thought of is that <=> uses splat-like parameter functionality and is sucking in the text after item 2, but I don't know why it would happen in a block statement but not outside of one or why it is ignoring the semicolon and newlines. A cursory search hasn't turned up any useful documentation.
Edit: The error I get when using Codeacadamy.com's compiler is "comparison of String with String failed."
Edit2:
ruby -e '
> list = ["one", "two", "three"]
> list.sort { |f, s| f <=> s; puts "foo" }
> puts list
> '
foo
-e:3:in `sort': comparison of String with String failed (ArgumentError)
from -e:3:in `<main>'
When you do this:
list.sort do |item1, item2|
item1 <=> item2
puts "foo"
end
Ruby looks at the return value of the block to determine the comparison. Since you have puts "foo"
at the end of the block, the result of the custom compare will be the output of puts "foo"
(which is nil
). You want the comparator to be the last thing you do in the block.