我试图了解块{ |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)
答案 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
如果您只需要提取keys
和values
,那么也可以。像:
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
我希望这可能会让你感到清楚..如果您有任何疑问,请随时提出。