这个问题已经有了答案:
What is the difference or value of these block coding styles in Ruby?
7答
对不起,如果这个问题是重复的。但我找不到用法上的区别。当我运行下面的代码时,我得到了不同的答案。我从大多数教程中看到使用“do…结束“与”{…}“块”。

include Comparable

a = [1, 4, 2, 3, 5]

p a.sort do |x,y|
    y <=> x
end

输出显示为=[1,2,3,4,5]
但当我这样跑的时候…
include Comparable

a = [1, 4, 2, 3, 5]

p a.sort { |x,y|
    y <=> x
}

输出显示为=[5,4,3,2,1]
这里出什么事了。有没有两种语法有不同的行为?

最佳答案

Sawa的回答是正确的,但是由于OP要求更多的澄清,我提供了我自己的答案。
所有这四个方法调用的行为都相同,将块传递给foo方法:

foo { ... }
foo do ... end
foo() { ... }
foo() do ... end

当您编写两个方法和一个块(参数周围没有括号)时,不清楚块与哪个方法一起使用:
foo bar { ... }
foo bar do ... end

问题是:“我是否将块传递给bar,然后将其返回值传递给foo?或者我用foo作为参数调用bar,同时传递一个块?”
使用圆括号,可以使用以下任一块样式来明确这一点:
# Passing a block to `bar`, and then passing the result to `foo`
foo( bar { ... } )
foo( bar do ... end )

# Passing an argument and  block to `foo`
foo( bar ) { ... }
foo( bar ) do ... end

您遇到的{…}do…end之间的区别在于,当您省略括号时,ruby选择将括号放在哪里。两个块符号具有不同的优先级,因此以不同的结果结束:
# Passing a block to `bar`, and then passing the result to `foo`
foo bar{ ... }
foo( bar do ... end )

# Passing an argument and  block to `foo`
foo bar do ... end
foo( bar ){ ... }

所以,特别是在你的情况下:
# This code…
p a.sort do |x,y|
    y <=> x
end

# …is the same as this code:
b = a.sort
p(b){ |x,y| y <=> x }

# Note that you are passing a block to the `p` method
# but it doesn't do anything with it. Thus, it is
# functionally equivalent to just:
p a.sort

而且,
# This code…
p a.sort { |x,y|
    y <=> x
}

# …is functionally the same as this code:
b = a.sort{ |x,y| y <=> x }
p b

最后,如果您仍然没有得到它,也许深入考虑以下代码和输出将有所帮助:
def foo(a=nil)
  yield :foo if block_given?
end

def bar
  yield :bar if block_given?
  :bar_result
end

foo bar { |m| puts "block sent to #{m}" }
#=> block sent to bar
#=> foo got :bar_result

foo( bar do |m| puts "block sent to #{m}" end )
#=> block sent to bar
#=> foo got :bar_result

foo( bar ){ |m| puts "block sent to #{m}" }
#=> foo got :bar_result
#=> block sent to foo

foo bar do |m| puts "block sent to #{m}" end
#=> foo got :bar_result
#=> block sent to foo

请注意,上面代码中的第一个和最后一个示例仅在对块使用{…}还是do…end方面有所不同。

10-07 19:30
查看更多