英文出自:yehudakatz.com,编译:CSDN赵红
常常会遇到有人将Ruby的区块(Blocks)看作相当于JavaScript的“first class functions ”的误解。由于传递功能,尤其是当你可以创建匿名的传递功能,这是非常强大的。事实上,JavaScript和Ruby有一个机制使其自然会认为等值。
人们在谈到为什么Ruby的区块不同于Python的函数时,通常会讲到一些关于Ruby和JavaScript的匿名分享,但Python没有。初看之下,一个Ruby区块就是一个“匿名函数”(或俗称一个“封装”),正如JavaScript函数就是其中之一。
作为一个早期的Ruby/JavaScript开发者,无可否认我也有过这样的观点分享。错过一个重要的细节,对结果会产生较大影响。这个原理常被称为“Tennent’s Correspondence Principle”,这条原理说:“For a given expression expr, lambda expr should be equivalent.”这就是被称为抽象的原则,因为这意味着,用“区块”的方法很容易重构通用代码。例如,常见文件资源管理的情况。试想在Ruby中,File.open块形式是不存在的,你会看到以下代码:
1 2 3 4 5 6 7 |
begin f = File.open(filename, "r") # do something with f ensure f.close end |
1 |
在一般情况下,“区块”代码有着相同的开始和结束编码、不同的内部编码。现在重构这段代码,你会这样写: |
1 2 3 4 5 6 |
def read_file(filename) f = File.open(filename, "r") yield f ensure f.close end |
1 |
代码中的模式与重构实例: |
1 2 3 |
read_file(filename) do |f| # do something with f End |
1 |
重要的是重构之后区块内的代码和以前一样 。在以下情况时,我们可以重申抽象原则的对应原理: |
1 |
# do something with f |
1 |
应相等于: |
1 2 3 |
do # do something with end |
乍一看,在Ruby和JavaScript中确实如此。例如,假设你正在使用的文件打印它的mtime。您可以轻松地重构相当于在JavaScript:
1 2 3 4 5 6 7 |
try { // imaginary JS file API var f = File.open(filename, "r"); span>= File.open(filename, "r"); 人们在谈到为什么Ruby的区块不同于Python的函数时,通常会讲到一些关于Ruby和JavaScript的匿名分享,但Python没有。初看之下,一个Ruby区块就是一个“匿名函数”(或俗称一个“封装”),正如JavaScript函数就是其中之一。
作为一个早期的Ruby/JavaScript开发者,无可否认我也有过这样的观点分享。错过一个重要的细节,对结果会产生较大影响。这个原理常被称为“Tennent’s Correspondence Principle”,这条原理说:“For a given expression expr, lambda expr should be equivalent.”这就是被称为抽象的原则,因为这意味着,用“区块”的方法很容易重构通用代码。例如,常见文件资源管理的情况。试想在Ruby中,File.open块形式是不存在的,你会看到以下代码:
乍一看,在Ruby和JavaScript中确实如此。例如,假设你正在使用的文件打印它的mtime。您可以轻松地重构相当于在JavaScript:
|