ruby块/ procs和方法调用

时间:2014-10-10 04:41:23

标签: ruby methods block proc

我试图了解块{ |s| puts s }的必要性:

  def accepts_hash( var )
    print "got: ", var.inspect # will print out what it received
  end

accepts_hash( { :arg1 => 'giving arg1', :argN => 'giving argN' } )  { |s| puts s } 

当我运行此代码时,无论是否有{ |s| puts s }

输出仍然是({ :arg1 => 'giving arg1', :argN => 'giving argN' })

有人可以解释阻止{ |s| puts s }在这里做什么吗?

(来源:http://en.wikibooks.org/wiki/Ruby_Programming/Syntax/Method_Calls

4 个答案:

答案 0 :(得分:1)

我相信您所引用的示例仅说明了如何将块传递给accepts_hash。该方法没有实现与块做任何事情,因此忽略它。

如果您有这样的定义:

def accepts_hash (var, &block)
...
  block.call
end

然后它需要一个显式的块参数并对其进行评估。这应该给出不同的输出。

请注意,所有ruby方法都隐式接受块,这就是为什么你能够传递一个块,即使方法签名没有要求它。

您可以更改实现以检查是否给出了块并对其进行评估。

示例:

def accepts_hash(var)
  ...
  yield if block_given?
end

yield关键字计算隐式传递的块。

答案 1 :(得分:1)

方法调用{ |s| puts s }之后的块在您告知之前不会执行任何操作。如果你继续阅读这个页面,他们会进一步向下解释 - 这是一个例子:

def accepts_hash( var )
  print "got: ", var.inspect    # will print out what it received
  yield ' jenny from the block' # pass value back to block
end

accepts_hash( { :arg1 => 'giving arg1', :argN => 'giving argN' } )  { |s| puts s }

=> {:arg1=>"giving arg1", :argN=>"giving argN"} jenny from the block

通过屈服,我们可以返回并处理块 - 在这种情况下,s代表我们正在产生的字符串,' jenny from the block'是它的值。

使ruby更灵活和声明,允许您编写惯用语和人类可读代码。例如:

3.times { p 'hello' } 
=> "hello"
=> "hello"
=> "hello"

ruby​​是一种华丽的语言 - 有关块和实际用法的更多信息:http://www.gotealeaf.com/blog/declarative-thinking-with-higher-order-functions-and-blocks

答案 2 :(得分:0)

当您定义accepts_hash时,您没有告诉它接受块参数。所以你的块目前被忽略了。要传入一个块,您需要在变量名称之前使用&符号作为参数。

def accepts_hash( var, &blck )
  print "got: ", var.inspect # will print out what it received
  puts
  print "block: ", blck[] # will print out what it received
end

accepts_hash( { :arg1 => 'giving arg1', :argN => 'giving argN' } )  { 123 } 
 # got: {:arg1=>"giving arg1", :argN=>"giving argN"}
 # block: 123 => nil 

或者,您可以使用yield来访问块。

def accepts_hash( var )
  print "got: ", var.inspect # will print out what it received
  puts
  print "block: ", yield # will print out what it received
end

accepts_hash( { :arg1 => 'giving arg1', :argN => 'giving argN' } )  { 123 } 
 # got: {:arg1=>"giving arg1", :argN=>"giving argN"}
 # block: 123 => nil 

相同的结果,传递一个块的不同方式。

答案 3 :(得分:0)

让我清楚你的怀疑,在你的代码中,你传递Hash作为方法的参数。

def accepts_hash( var )
    print "got: ", var.inspect # will print out what it received
end

accepts_hash( { :arg1 => 'giving arg1', :argN => 'giving argN' } ) 

{ |s| puts s }这不会被视为var中的参数。

{ |s| puts s }通常用于获取哈希的所有键和值。

对于E.g

ab = {:arg1 => 'giving arg1', :argN => 'giving argN'}

ab.each { |s| puts s }
#Output: 
argN # 1st key
giving argN  # 1st key's value
arg1 # 2nd key
giving arg1 # 2nd key's value

如果您只需要提取keysvalues,那么也可以。像:

ab.each { |key, value| puts key } 
=> argN
   arg1

在你的方法中,如果你只想访问传递的Hash的keys作为参数,那么

def accepts_hash( var )
        puts "Keys:=> ", var.keys # will take all keys of Hash
        puts "Values:=>", var.values # will take all values of Hash
end

accepts_hash( { :arg1 => 'giving arg1', :argN => 'giving argN' } )

关于yielding所描述的@lfender6445,您可以通过使用{ |s| puts s }方法进行某些修改来查看split阻止效果。

,例如

def accepts_hash( var )
  print "got: ", var.inspect   # inspect will print the whole object the way it gets
  yield ' pass value back to block'
end

accepts_hash( { :arg1 => 'giving arg1', :argN => 'giving argN' } )  { |s| puts s.split }
Output => got: {:argN=>"giving argN", :arg1=>"giving arg1"}pass
value
back
to
block

我希望这可能会让你感到清楚..如果您有任何疑问,请随时提出。