“结束”的不同行为。和" {..}"红宝石块

时间:2016-06-05 03:24:18

标签: ruby

很抱歉,如果这个问题是重复的。但我无法找到使用上的差异。当我运行以下代码时,我得到了不同的答案。我从大多数教程中看到使用" do ... end"与" {...}"相同块。

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]

这里出了什么问题。是否存在两种语法有任何不同行为的情况?

3 个答案:

答案 0 :(得分:5)

优先顺序不同。第一个被解释为

p (a.sort) do
  ...
end

由于该块未传递给sort,因此将按默认的升序排序。然后,块传递给ppublic class IngoingReceiver extends BroadcastReceiver { int previousState = 2; public void onReceive(final Context context, Intent intent) { ITelephony telephonyService; TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); try { Class c = Class.forName(tm.getClass().getName()); Method m = c.getDeclaredMethod("getITelephony"); m.setAccessible(true); telephonyService = (ITelephony) m.invoke(tm);`enter code here` Bundle bundle = intent.getExtras(); String phoneNumber = bundle.getString("incoming_number"); Log.e("INCOMING", phoneNumber); if ((phoneNumber != null)) { telephonyService.silenceRinger(); telephonyService.endCall(); Log.e("HANG UP", phoneNumber); } } catch (Exception e) { e.printStackTrace(); } } } package com.android.internal.telephony; public interface ITelephony { boolean endCall(); void answerRingingCall(); void silenceRinger(); } 不使用它。

答案 1 :(得分:3)

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# 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 ){ ... } 之间的区别在于Ruby选择在省略括号时放置括号。两个块符号具有不同的优先级,因此您以不同的结果结束:

# 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…endos.getcwd()

答案 2 :(得分:2)

正如其他人所指出的,两种类型的块之间的优先级存在差异。但是,优先权并没有真正影响它在实践中的使用方式。

有些Rubyist会关注Weirich Conventionnamed so by Avdi Grimm

简而言之,一个使用另一个是基于它是否正常(使用返回值),在这种情况下使用{ ... },还是程序性的(以某种方式改变系统的状态或执行输出),在这种情况下使用do ... end