真的骄傲梦想家园
专业源于兴趣和努力

代码块和迭代器

这节简单地介绍Ruby的其中一个特长。我们将要学习的是代码块:一些能和方法关联在一起调用的代码,它们简直就像是方法的参数一样。

这是一个难以置信的强大特性。我们其中一个评论家对这个特性是这样评论的:“这真的很有趣,而且很重要,如果以前你没有注意到它,

那么你现在就要开始关注了。”我们都同意他的观点。

你可以使用代码块实现回调(但它们比较Java的匿名内联函数简单多了),传入一个代码块(但它们比较C的方法指针要安全得多),然后实现迭代。

代码块仅仅是一些在花括号或do...end间的代码。

{ puts "Hello" } # this is a block
do ###
club.enroll(person) # and so is this
person.socialize #
end ###


为什么会有两种分隔符呢?其中一个原因是有时候会觉得其中一个比另一个用得更自然。另一个原因是它们的优先级不同:花括号比较do/end对优先级更高。

在本书中,我们将尽量按照即将成为Ruby标准的用法,单行代码使用花括号,多行代码使用do/end。

一旦你创建了一个代码块,你就能把它和方法一起关联调用。只要把代码块放在包含方法调用的代码后面就行了。

例如,下面的代码中,一个包含puts "Hi"的代码和一个greet方法关联调用。

greet { puts "Hi" }

 

如果方法包含有参数,把它们放在花括号的前面。

verbose_greet("Dave", "loyal customer") { puts "Hi" }

 


使用Ruby的yield,一个与方法关联的代码块能执行一次或多次。你可以把yeild想象成一种方法的调用,它能调用与包含有yield的方法相关联的代码块。

下面通过实际的例子来演示。我们定义一个调用了yield两次的方法,把代码块放在和方法同一行上,在方法的调用后面(并且是在方法的所有参数后面)。

Code

 

仔细看下在代码块中的代码(puts "In the block")是怎么执行两次的,一个yield执行一次。

你可以在调用yield的时候给它提供参数:这些参数会传递到代码块中。在代码块内,你在两个竖线(|)之间列出要接收的参数的名字。

Code

 

在整个Ruby类库中都是使用代码块实现迭代:一种能从各种集合,如数组中,返回连续的元素的方法。

animals = %w( ant bee cat dog elk ) # create an array
animals.each {|animal| puts animal } # iterate over the contents
produces:
ant
bee
cat
dog
elk

 


让我们来看一下上面的例子中,数组类是怎样使用代码块实现each迭代的。each迭代循环数组中的每个元素并调用yield。

在伪代码中,它们可能看起来会像这样

# within class Array
def each
for each element # <not valid Ruby
yield(element)
end
end

 


许多编程语言如C和Java内置的循环结构在Ruby中都不过是简单的方法调用,调用0次或多次与方法关联的代码块。

[ 'cat', 'dog', 'horse' ].each {|name| print name, " " }
5.times { print "*" }
3.upto(6) {|i| print i }
(
'a'..'e').each {|char| print char }
produces:
cat dog horse
*****3456abcde

 


这里,我们让对象5调用代码块5次,让对象3调用一个代码块,并给它传递从3到6的连续值。最后,从a到e这个范围的字符分别调用代码块各一次。

输入和输出

Ruby自带有一个综合的I/O库。然而,在本书的大部分例子中,我们仍然使用一些简单的方法。我们已经使用了两个用于输出的方法。

puts输出它的参数,并转到下一行。print也是输出它的参数,但它不会换行。它们都能用于输出到任意的I/O对象,但默认是输出到标准输出中。

另一个我们用得比较多的输出方法是printf,它把参数在格式字符串的控制下输出(和C或Perl中的printf一样)。

printf("Number: %5.2f,\nString: %s\n", 1.23, "hello")
produces:
Number:
1.23,
String: hello

 


在这个例子中,格式化字符串"Number: %5.2f,\nString: %s\n"告诉printf使用一个浮点数(总共允许5个字符,其中两个在小数点后面)

和一个字符串替代。注意到换行符(\n)在这个字符串内;每个换行符都会使用输出换到下一行。

你可以通过多种途径把输入读到程序中。可能最经典的是使用常用的gets,它返回标准输入流的下一行到程序中。

line = gets
print line

posted on 2008-11-29 23:12  真的骄傲  阅读(1512)  评论(1编辑  收藏  举报