Sort and a multiline block

  • Thread starter Raymond O'Connor
  • Start date
R

Raymond O'Connor

Using sort with a multiline block doesn't seem to work as expected.

Single line blocks work fine:

[3, 7, 4, 1, 8, 2, 8, 9].sort { |a, b| a <=> b }
#returns [1, 2, 3, 4, 7, 8, 8, 9]

[3, 7, 4, 1, 8, 2, 8, 9].sort { |a, b| b <=> a }
#returns [9, 8, 8, 7, 4, 3, 2, 1]



Multiline blocks ALWAYS sort in ascending order for some reason:

[3, 7, 4, 1, 8, 2, 8, 9].sort do |a, b|
a <=> b
end
#returns [1, 2, 3, 4, 7, 8, 8, 9]

[3, 7, 4, 1, 8, 2, 8, 9].sort do |a, b|
b <=> a
end
#returns [1, 2, 3, 4, 7, 8, 8, 9]


In fact even when I code the comparison by hand, it's still always
ascending:

[3, 7, 4, 1, 8, 2, 8, 9].sort do |a, b|
if a < b
1
elsif a > b
-1
else
0
end
end
#returns [1, 2, 3, 4, 7, 8, 8, 9]




Does anyone know what's going wrong with this?

Thanks
 
I

Ilan Berci

Raymond said:
Using sort with a multiline block doesn't seem to work as expected.

Single line blocks work fine:

[3, 7, 4, 1, 8, 2, 8, 9].sort { |a, b| a <=> b }
#returns [1, 2, 3, 4, 7, 8, 8, 9]

[3, 7, 4, 1, 8, 2, 8, 9].sort { |a, b| b <=> a }
#returns [9, 8, 8, 7, 4, 3, 2, 1]

works for me.. perhaps it's something else in your code

irb(main):009:0> a = [3,7,4,1,8,2,8,9]
=> [3, 7, 4, 1, 8, 2, 8, 9]
irb(main):010:0> a.sort do |b,c|
irb(main):011:1* b <=> c
irb(main):012:1> end
=> [1, 2, 3, 4, 7, 8, 8, 9]
irb(main):013:0> a.sort do |b,c|
irb(main):014:1* c <=> b
irb(main):015:1> end
=> [9, 8, 8, 7, 4, 3, 2, 1]

ilan
 
P

Phrogz

[3, 7, 4, 1, 8, 2, 8, 9].sort do |a, b|
b <=> a
end
#returns [1, 2, 3, 4, 7, 8, 8, 9]

I do not get this result; I get what you expected.

What OS are you running, including version?
What version of Ruby? Did you hand compile it, or use an installer.

Can you show 'proof' in the form of a single program that does that
above, showing that you are for sure getting this result with exactly
this code?
 
R

Raymond O'Connor

I'm having the problem using

Ruby 1.8.5 with Mac OS X 10.4.10
Ruby 1.8.6 with Leopard


The interesting thing is when I run the commands on irb, I get the
correct results, but when I run them through Textmate, the result is
always sorted ascending.
 
C

Collin VanDyck

I'm having the problem using

Ruby 1.8.5 with Mac OS X 10.4.10
Ruby 1.8.6 with Leopard

The interesting thing is when I run the commands on irb, I get the
correct results, but when I run them through Textmate, the result is
always sorted ascending.

I'm on Leopard, and this program:

#!/usr/bin/env ruby

result = [3, 7, 4, 1, 8, 2, 8, 9].sort do |a, b|
b <=> a
end
p result

Run from within TextMate gives me

[9, 8, 8, 7, 4, 3, 2, 1]

I think that you've probably got something else going on in your
program. As someone else said, post a short program in its entirety
that will illustrate what you're seeing.
 
R

Raymond O'Connor

When I store the result of the sort, everything is fine:

Correct
result = [2, 4, 3, 7, 1, 8, 9, 8].sort do |a, b|
b <=> a
end

p result #[9, 8, 8, 7, 4, 3, 2, 1]




But when just do a p on the sort, the problem occurs

Incorrect
p [2, 4, 3, 7, 1, 8, 9, 8].sort do |a, b|
b <=> a
end #[1, 2, 3, 4, 7, 8, 8, 9]
 
T

Todd Benson

When I store the result of the sort, everything is fine:

Correct
result = [2, 4, 3, 7, 1, 8, 9, 8].sort do |a, b|
b <=> a
end

p result #[9, 8, 8, 7, 4, 3, 2, 1]




But when just do a p on the sort, the problem occurs

Incorrect
p [2, 4, 3, 7, 1, 8, 9, 8].sort do |a, b|
b <=> a
end #[1, 2, 3, 4, 7, 8, 8, 9]

May have something with how the parser sees do/end, (), and {}
precedence. Interesting.

p [2, 4, 3, 7, 1, 8, 9, 8].sort do |a, b|
b <=> a
end #[1, 2, 3, 4, 7, 8, 8, 9]

p [2, 4, 3, 7, 1, 8, 9, 8].sort { |a, b|
b <=> a
} #[9, 8, 8, 7, 4, 3, 2, 1]

p( [2, 4, 3, 7, 1, 8, 9, 8].sort do |a, b|
b <=> a
end
) #[9, 8, 8, 7, 4, 3, 2, 1]

You can see the same behavior with...

p [1, 2, 3].map do |i|
i + 1
end #[1, 2, 3]

p [ 1, 2, 3].map { |i|
i + 1
} #[2, 3, 4]

Todd
 
P

Phrogz

When I store the result of the sort, everything is fine:
Correct
result = [2, 4, 3, 7, 1, 8, 9, 8].sort do |a, b|
b <=> a
end
p result #[9, 8, 8, 7, 4, 3, 2, 1]
But when just do a p on the sort, the problem occurs
Incorrect
p [2, 4, 3, 7, 1, 8, 9, 8].sort do |a, b|
b <=> a
end #[1, 2, 3, 4, 7, 8, 8, 9]

May have something with how the parser sees do/end, (), and {}
precedence. Interesting.

Exactly.

This line:
p foo { ... }
is interpreted as
p( foo{ ... } )

While this line:
p foo do ... end
is interpreted as
p(foo) do ... end

The lower precedence of do/end is causing it to be bound to the result
of p( foo ), or in your case p( array.sort )
 
P

Peña, Botp

From: Phrogz [mailto:p[email protected]]=20
# This line:
# p foo { ... }
# is interpreted as
# p( foo{ ... } )
#=20
# While this line:
# p foo do ... end
# is interpreted as
# p(foo) do ... end
#=20
# The lower precedence of do/end is causing it to be bound to the result
# of p( foo ), or in your case p( array.sort )

indeed, but the sad part really is ruby does not check blocks, like as =
if they float silently like shadows :(=20

eg
p{|x| p x}
=3D> nil
puts{|x| p x}

=3D> nil
"sdf".upcase{|x| p x}
=3D> "SDF"
def m
end
=3D> nil
m{|x| p x}
=3D> nil

i would consider those as bugs though :(

i just wish blocks were like clear and visible proc params.

kind regards -botp
 
R

Raymond O'Connor

Gavin said:
This line:
p foo { ... }
is interpreted as
p( foo{ ... } )

While this line:
p foo do ... end
is interpreted as
p(foo) do ... end

The lower precedence of do/end is causing it to be bound to the result
of p( foo ), or in your case p( array.sort )

Really interesting. I never realized that do/end had lower precedence
than {}. Thanks for the help everyone!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,161
Messages
2,570,892
Members
47,431
Latest member
ElyseG3173

Latest Threads

Top