了解如何调用ruby方法

时间:2015-04-26 19:29:10

标签: ruby function methods

我有一个java背景。我在ruby中提出了一个可以作为

调用的方法
Oj::Doc.open('[1,2,3]')

以及

Oj::Doc.open('[1,2,3]') { |doc| doc.size() }

第一种类似于java方法,但我不明白在第二种情况下发生了什么。有人可以给我一些澄清吗?

3 个答案:

答案 0 :(得分:2)

Ruby中的所有东西都是一个对象。以下是block的示例。阻挡只不过是块了。

 { |doc| doc.size() }

ruby​​中的方法可以接受任意数量的参数,参数只是对象。因此将块传递给方法就像将对象传递给方法一样。

def a_method(arg)
  return arg + yield(arg) if block_given?
  arg
end
a_method(3) #=> 3
a_method(3) { |x| x + 4 } #=> 10

在上面的示例中,如果提供了块,block_given?将计算为trueyieldself的上下文中评估块。 self只不过是当前的对象。对该块进行求值,并将闭包传递给块(上面为x),并将其计算并返回a_method

使用特殊的&运算符证明块是对象非常简单:

def return_block(&block)
  block
end
return_block { |x, y| x + y }
#=> #<Proc:0x007fe28b53aa50@(pry):65>

Proc是块的对象表示 在第一个示例中,您看到a_method的参数列表中未明确提及块,但可以使用特殊的yield关键字。 &block是获取块作为参数的方法。

第一个例子可以重写如下:

def a_method(arg, &block)
  return arg + block.call(arg) if block
  arg
end

a_method(3) #=> 3
a_method(3) { |x| x + 4 } #=> 10

创建块对象的另一种方法:

block = Proc.new { |x| x + 4 }
# Similarly, you can pass the block (object) as explicit argument
a_method(3, &block)

对于您的原始问题,您也可以这样做:

block = Proc.new { |doc| doc.size() }
Oj::Doc.open('[1,2,3]', &block)

这使您可以动态管理块,对象和方法。

纯粹的超棒Ruby。 &LT; 3

答案 1 :(得分:1)

您可以将块传递给方法。块是包含可执行行的闭包。

可以使用do end或花括号{}来定义块,您已经看过花括号版本,这里是替代...

Oj::Doc.open('[1,2,3]') do |doc| 
  doc.size()  
end

并非所有方法都需要一个块,但如果它被传递,则可以使用yield关键字在方法中执行。它们也可以转换为Procs或Lambdas,它们是对象(普通块不是对象)

如果块接受一个或多个参数,则它们在垂直条内传递。在这个例子中......

[1, 2, 3].each { |number| print number }

...该块将被生成三次,对于数组中的每个元素一次,并且数组元素由number参数引用。

答案 2 :(得分:1)

在Ruby中,每个方法都可以占用一块。除了您在代码的第一种形式中传递的参数外,您的第二种代码形式还有一个未命名的块传递给该方法。

许多方法对块没有任何作用。但这不会导致错误。如果实际使用该块,则此方法将调用def ruby_method yield if block_given? end 来评估方法中的块。

当Ruby方法使用块时,它可能如下所示:

ruby_method

此示例使用“匿名”块,并且yield将控制权返回到调用[Parents] int ParentId string LName virtual List<Child> Children [Child] int ChildId int ParentId int Count 的程序。