块参数的基本原理是什么?

时间:2017-02-04 14:09:58

标签: ruby

我刚刚学习了Ruby,并且很难看到所谓的"块参数" (可以附加到方法调用中)。

AFAICT,"阻止参数"就像其他编程语言中的任何普通回调参数一样(或者在Ruby本身,就此而言),但更有限的是,最多可以附加一个"块参数"一个方法调用,虽然回调参数的数量没有上限,方法/函数可以设计为接受。

(如果需要澄清,通过"回调"我的意思是一个函数 F 另一个函数 G 接收(作为其中一个参数)并依次调用。)

我认为必须有某些东西可以使用块参数来完成就像使用回调一样容易(否则,它&很难证明支持块参数的特殊语法是合理的,但是我无法弄清楚这个"是什么"可能是。

我的问题就是:

使用"块参数"可以做些什么?通过常规回调无法做到这一点?

编辑:早期的评论(现已删除)表示,块参数更好地描述为"闭包"而不是"回调"。在我的书中,闭包是回调的特例。如果有人愿意,可以替换“回调”#34;用"关闭"在我的帖子中。帖子的问题仍然存在(当然,除非#34;块参数和#34;是在Ruby中创建闭包的唯一方法,但如果是这种情况,它本身会引发更多的问题而不是它答复)。

2 个答案:

答案 0 :(得分:2)

我认为使用传递函数(例如在javascript中)无法完成任何操作都无法做到。 我认为ruby的创建者认为,在95%的情况下,你只希望将一个回调传递给一个函数,而不是更多。所以他们为此创建了非常好的语法:

 Post.all.map { |post| puts post.title } 

与javascript比较

$(document).on('click', function() {
   DO SOMETHING
 }

总结:我认为传递块是ruby中的语法糖,可与js中的传递函数相媲美,但更好看。在大多数情况下,您仍然希望传递一个块(或回调)。

答案 1 :(得分:2)

  

我认为必须有一些可以用块参数做的事情,这些事件不能通过回调轻松完成(否则,

是。块是一种"语法糖",但它们在功能上与"回调函数"完全不同。用JavaScript这样的语言。

首先,return关键字的功能与Ruby和其他语言中的函数和方法的功能完全不同。

在一个区块内,return跳出包含方法,而方法return跳出(显然)方法。

这对以下情况非常重要:

def find_by_email(users, search_email)
  users.each do |user|
    # return all the way out of find_by_email
    return user if user.email == search_email
  end

  nil
end

在这里,我们使用each来迭代集合。如果我在块中有一些条件,那么用户将被从包含方法返回。

这不适用于某项功能。比较"相同的" JavaScript代码,它没有按预期工作:

function findUserByEmail(users, searchEmail) {
  users.forEach(function (user) {
    if (user.email == searchEmail) {
      // return out of `forEach`
      return user;
    }
  });
  // broken
}