我是一个Java程序员,我正在学习Ruby ...与常规方法相比,块可以获得什么收益?
但是我不明白那些代码块可以让我获得...就像传递块作为参数的目的是什么?为什么不有两种专门的方法可以重用?
为什么块中有一些代码不能被重用?
我喜欢一些代码示例...
感谢您的帮助!
我是一个Java程序员,我正在学习Ruby ...与常规方法相比,块可以获得什么收益?
但是我不明白那些代码块可以让我获得...就像传递块作为参数的目的是什么?为什么不有两种专门的方法可以重用?
为什么块中有一些代码不能被重用?
我喜欢一些代码示例...
感谢您的帮助!
考虑在Java中使用匿名类的一些方面。例如通常它们用于可插入的行为,如事件侦听器或参数化具有常规布局的方法。
想象一下,我们想要编写一个方法,该方法接受一个列表并返回一个新列表,该列表包含给定列表中指定条件为真的项目。如果我们想选择即使从列表编号
public List select(List list, Condition c) {
List result = new ArrayList();
for (Object item : list) {
if (c.f(item)) {
result.add(item);
}
}
return result;
}
,然后我们可以这样写:在Java中,我们会写一个接口:
interface Condition {
boolean f(Object o);
}
,然后我们可以写
List even = select(mylist, new Condition() {
public boolean f(Object o) {
return ((Integer) o) % 2 == 0;
}
});
要在Ruby中编写等价物,它可能是:
def select(list)
new_list = []
# note: I'm avoid using 'each' so as to not illustrate blocks
# using a method that needs a block
for item in list
# yield calls the block with the given parameters
new_list << item if yield(item)
end
return new_list
end
,然后我们就可以选择甚至干脆
even = select(list) { |i| i % 2 == 0 }
当然号,这个功能已经内置到红宝石因此在实践中,你只想做
even = list.select { |i| i % 2 == 0 }
再举一个例子,考虑代码打开一个文件。你可以这样做:
f = open(somefile)
# work with the file
f.close
但那么你就需要考虑把close
在你的ensure
块中,以防发生异常,而与文件的工作。相反,你可以做
open(somefile) do |f|
# work with the file here
# ruby will close it for us when the block terminates
end
嗯......谢谢,这是一个很好的例子......我想我需要一些时间来习惯这样想。但那就是为什么我试图学习Ruby:当你得到它时,它是一个很好的解决方案。 – 2011-01-24 16:00:47
块背后的想法是,它是一个高度本地化的代码,它有助于在呼叫站点进行定义。您可以使用现有的函数作为块参数。只要将它作为附加参数传递,并在前缀为&
除了下面的回答,请注意,在Ruby中块_closures_,方便客人在同一范围内定义的局部变量,而无需显式地将它们传递到一些方法。 – Phrogz 2011-01-24 18:14:09