积木Ruby中的Procs [英] Blocks & Procs in Ruby

查看:85
本文介绍了积木Ruby中的Procs的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经开始学习Ruby,并且阅读了一些教程,甚至还买了一本书("Ruby 1.9编程-实用程序员指南"),并且遇到了一些以前从未见过的新东西.用我所知道的任何其他语言(我正在以PHP网络开发人员的身份).

I have started learning Ruby, and I have read a couple of tutorials and I even bought a book ("Programming Ruby 1.9 - The Pragmatic Programmers' Guide"), and I came across something new that I haven't seen before in any of the other languages I know (I am working as a PHP webdeveloper).

块和程序. 我想我了解它们的含义,但是我不了解的是它们为什么这么好,以及何时以及为什么应该使用它们. 在我看来,他们到处都说块和proc是Ruby的一个很棒的功能,但我不理解它们.

Blocks & Procs. I think I understand what they are, but what I don't understand is why they are so great, and when and why I should use them. Everywhere I look they say blocks and procs are a great feature in Ruby, but I don't understand them.

这里有人可以给像我这样的Ruby新手一些解释吗?

Can anybody here give a total Ruby-newbie like me some explanations?

推荐答案

关于块有很多优点.电梯音高:块使我们可以像通常传递 data 一样传递 action .

There are a lot of things that are good about blocks. The elevator pitch: Blocks let us pass around actions the same way we normally pass around data.

最明显的层次是,它们使您可以将事物抽象为其他函数无法实现的功能.例如,让我们看一个常见的情况,即您拥有一个事物列表,并且想要对其进行过滤以仅包含符合某些条件的项目:

The most obvious level is that they let you abstract things out into functions that wouldn't be possible otherwise. For example, let's look at a common case where you have a list of things and you want to filter it to only include items that match some criterion:

int list[50] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50};
int evenNumbers[50] = {0};
int copyIndex = 0;
for (int i = 0; i < 50; i++) {
    if (list[i] % 2 == 0) {
        evenNumbers[copyIndex++] = list[i];
    }
}

这是您在Ruby中编写代码的方式:

Here's how you write that in Ruby:

list = 1..50
listCopy = list.select {|n| n.even?}

所有常见的工作都从代码中移出,并移到了一个有意义的名称方法中.我们不在乎复制数组和遍历索引等所有操作,我们只需要一个过滤列表.这就是select给我们的.该块使我们可以将自定义逻辑传递到此标准方法中.

All the common busywork is moved out of your code and into a method with a meaningful name. We don't care about copying the array and going through indexes and all that — we just want a filtered list. And that's what select gives us. The block allows us to pass our custom logic into this standard method.

但是,迭代器并不是唯一的地方中间的孔"是有用的.例如,如果将一个块传递给File.open,它将打开文件,对该文件执行该块,然后为您关闭文件.

But iterators aren't the only place where this "hole in the middle pattern" is useful. For example, if you pass a block to File.open, it will open the file, execute the block with the file and then close the file for you.

阻止提供给我们的另一件事是一种非常强大的回调形式.例如,在没有块的情况下,我们可能必须执行以下操作(基于对话框在Objective-C Cocoa中的实际工作方式):

Another thing that blocks give us is a really powerful form of callbacks. For example, without blocks, we might have to do something like this (based on how dialogs actually work in Objective-C Cocoa):

class Controller
  def delete_button_clicked(item)
    item.add_red_highlight
    context = {:item => item}
    dialog = Dialog.new("Are you sure you want to delete #{item}?")
    dialog.ok_callback = :delete_OK
    dialog.ok_receiver = self
    dialog.cancel_callback = :cancel_delete
    dialog.cancel_receiver = self
    dialog.context = context
    dialog.ask_for_confirmation
  end

  def delete_OK(sender)
    delete(sender.context[:item])
    sender.dismiss
  end

  def cancel_delete(sender)
    sender.context[:item].remove_red_highlight
    sender.dismiss
  end
end

Yowza.使用块,我们可以改为执行此操作(基于许多Ruby库中使用的通用模式):

Yowza. With blocks, we could do this instead (based on a common pattern used in many Ruby libraries):

class Controller
  def delete_button_clicked(item)
    item.add_red_highlight
    Dialog.ask_for_confirmation("Are you sure you want to delete #{item}?") do |response|
      response.ok { delete item }
      response.cancel { item.remove_red_highlight }
    end
  end
end

实际上是两个级别的块-do...end块和两个{}样式的块.但这听起来很自然,不是吗?之所以可行,是因为块捕获了创建它的上下文,因此我们不需要传递selfitem.

That's actually two levels of blocks — the do...end block and the two {}-style blocks. But it reads pretty naturally, doesn't it? This works because a block captures the context it's created in, so we don't need to pass around self and item.

对于Procs,它们只是块的对象包装.对他们来说不是很多.

As for Procs, they're just an object wrapper for blocks. Not very much to them.

这篇关于积木Ruby中的Procs的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆