我不了解Ruby Proc的想法...为什么不只使用常规方法?

问题描述

| 我想标题就是这样。我正在读一本书,可以看到它们的工作原理,但是为什么我要创建它们而不是使用带有常规参数的常规方法呢? 我搜索了Google,因此感到更加困惑。 请说清楚。谢谢。     

解决方法

        proc不同,因为您可以将其存储在变量中。因此,您可以将其作为参数传递给函数,从函数返回它,进行操作等。 Procs,lambda和block是使Ruby很棒的主要因素之一,例如,它们是Ruby迭代器的核心。当您执行以下操作时:
collection.each do |item|
 //process item
end
您基本上是将一个块(Proc对象)传递给每个函数。 假设您要以相同的方式处理一堆数组。为了避免每次编写每个代码,您可以执行以下操作:
handler = Proc.new{|item| do_something_with(item)}
array1.each &handler
array2.each &handler
....
arrayn.each &handler
如果要将Proc作为块传递给函数,则必须在前面加上
&
。当您定义一个接受块参数的函数时,情况也是如此。 使用Proc的另一种有用方法是在函数中。 假设您有一个实例化对象,进行一些小的更改并返回它的函数。为了使其更加灵活,您可以使它接受如下所示的块:
def new_item(param1,param2,&block)
  my_item = Item.new
  my_item.attribute1 = param1
  my_item.attribute2 = param2
  yield my_item if block_given?\\
  return my_item
end
产量是魔术发生的地方。评估该行后,该函数将使用my_item作为参数执行您为其提供的块。因此,您可以执行以下操作:
my_new_item = new_item(p1,p2) do |item|
  item.attribute3 = some_value
end
现在,
my_new_item
将设置为
attribute3
,以及您在程序段中所做的任何其他修改。 您不使用Procs和Lambda替换函数,而是使用它们来增强功能。 您可以有一个函数,该函数返回基于您提供的任何参数构建的Proc。使用Procs可以有很多创意方法。     ,        可以将Procs作为对象传递,并在需要时调用。这对于模块化(以及其他功能)和延迟处理很有用。一个示例是ActiveRecord允许Procs进行验证的方式。一些例子:
validates_presence_of :admin_password,:if => Proc.new{|u| u.admin?}
在这种情况下,只要执行验证,就会调用(并重用)Proc。     ,        过程-只是“方法”带有延迟的呼叫。您可以在proc中保存一些代码,然后在以后执行。很难解释在哪里可以使用它们,我将尝试从我的项目中获取示例。     ,        方法是您必须知道如何调用的具体方法。过程和块是可以随意传递和使用的任意代码单元。我想,您可以将Proc视为一种封闭。 当您的方法需要Proc中存储的任何代码的帮助时,请使用Proc。也许有一些逻辑可以从某个地方加载资源,或者其他不平凡的东西。与块不同,Procs旨在保留在变量中。     ,        好的问题,回答这个问题后,您将清楚知道在哪里以及如何使用Proc。 据我了解,Proc的优点是您可以将Proc作为参数传递给其他方法。当您定义常用方法时,该方法绑定到当前上下文并且无法更改,因此您无法将此方法传递给其他地方。但是使用Proc,您可以做到这一点。所有迭代器都使用此魔术。您只需要说要处理数组中的每个项目(创建了proc对象)并传递给iterator,然后iterator将此方法作为对象并在其功能中深入执行。     ,        另一个常见用途是简化构造为解释器的内容。假设您有某种类型的计算器,则可以这样做(将运算符及其定义之间的关联分开):
def add(a,b); a + b; end
def sub(a,b); a - b; end
#...
if(op == \'+\')
    add(a,b)
elsif(op == \'-\')
    sub(a,b)
#...
else
    raise \'Unknown operator\'
end
或者,您可以使用Lambda使其更整洁,更紧凑(例如,将运算符及其定义放在一起以使正在发生的事情变得显而易见):
ops = {
    \'+\' => lambda { |a,b| a + b },\'-\' => lambda { |a,b| a - b },#...
}
raise \'Unknown operator\' if(!ops.has_key?(op))
ops[op].call(a,b)
后一种方法也使特殊情况更加突出(恕我直言)。 一旦习惯了这种方法,就可以将数量惊人的事物构造为自定义数据结构的解释器。     

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...