2013-03-19 97 views
0

我在学习Ruby的时候注意到,每种方法的这些用法都工作并产生相同的输出,而且我想知道Ruby是如何实现这种功能的(以及我如何使它实现我自己的功能):Ruby:超载收益函数

my_array = [["hello","goodbye"],["picture","perfect"]] 

my_array.each do |array| 

    puts array[0] + " " + array[1] 

end 

my_array.each do |first, second| 

    puts first + " " + second 

end 

我理解的是写入一个接受代码块的方法的定义的情况下,产量的方法是利用将参数传递到码块,并调用块。但是,如何利用yield方法来根据所提供的代码块传递不同的参数?在这个例子中,看起来yield方法在块内使用两个参数(即第一个,第二个)时传递单个数组元素,并且当在块内使用一个参数时,它传递数组本身(即数组)。

+0

@RoneyMichael纠正我,如果我错了,但我不认为这是一个解决方案。 splat操作符旨在用于参数,而不是参数。而我的问题是关于如何构建我的产量陈述和我传递给他们的论点。 – voltair 2013-03-19 06:34:19

+0

哦对!我的错。 – 2013-03-19 07:37:32

回答

1

each而不是yield都没有做任何特殊的事情,这就是块参数的工作方式。考虑一个简单的例子:

def f(x) yield x end 

现在我们可以看看会发生什么:

>> f([1,2]) { |a| puts a.inspect } 
[1, 2] 
>> f([1,2]) { |a, b| puts "#{a} - #{b}" } 
1 - 2 
>> f([1,2]) { |a, b, c| puts "#{a} - #{b} - #{c}" } 
1 - 2 - 

你会在分配看到类似自毁:

a, b = [1, 2] 

您也可以做到这一点明确a splat:

a, b = *[1, 2] 

或像这样:

def g(x) yield *x end 
g([1, 2]) { |a, b| puts "#{a} - #{b}" } 

想必块知道各种各样的事情会被赋予这样的块,能很好地解压缩参数。请注意,g函数必须知道它的参数是splatable(即数组),但f不是。 f很好地把“x”这个逻辑放在f的呼叫中,g掩埋了它自身内部的一半逻辑。一个地方的差异变得很明显是当你使用一个散列可枚举的方法:

{ :where => :is, :pancakes => :house? }.map { |k, v| ... } 

Enumerable#map并不需要知道一个哈希键/值的两个元素数组的作品,它只是通过周围的事物和叶它让所有人都担心细节。

+0

非常感谢你的回答。那么在那里我可以看到ruby如何自动检测和解构(或不解构)这些对象(如数组和哈希)的规则吗?或者它只是通过反复试验学到的东西,因为它真的只是与数组和哈希值相关?另外,对于g方法,如果传递给g的参数不是数组,那么yield函数中的splat是否意味着会出现错误?并且只有阵列可以运行?这似乎是你推断的,但我不确定。 – voltair 2013-03-20 01:27:29

+0

@ user1419674:只有数组在块参数中获得自动触发/解构。如果你想看看如何与['Enumerable'](http://ruby-doc.org/core-2.0/Enumerable.html)(地图和朋友的来源)进行交互,那么你必须检查班级的文件。 – 2013-03-20 03:51:12