今天,我很惊讶地发现ruby会自动找到作为块参数给出的数组的值。

例如:

foo = "foo"
bar = "bar"
p foo.chars.zip(bar.chars).map { |pair| pair }.first #=> ["f", "b"]
p foo.chars.zip(bar.chars).map { |a, b| "#{a},#{b}" }.first #=> "f,b"
p foo.chars.zip(bar.chars).map { |a, b,c| "#{a},#{b},#{c}" }.first #=> "f,b,"

我本以为最后两个示例会给出某种错误。
  • 这是 ruby 中更一般概念的示例吗?
  • 我认为问题开头的措词不正确,我怎么称呼这是怎么回事?
  • 最佳答案

    Ruby的块机制对此有一个怪癖,那就是如果您要遍历包含数组的内容,则可以将它们扩展为不同的变量:

    [ %w[ a b ], %w[ c d ] ].each do |a, b|
      puts 'a=%s b=%s' % [ a, b ]
    end
    

    当使用Hash#each时,当您想分解成对的keyvalue部分时,此模式非常有用:each { |k,v| ... }在Ruby代码中非常常见。

    如果您的块接受多个参数,并且要迭代的元素是一个数组,则它将切换如何解释参数。您可以随时强制展开:
    [ %w[ a b ], %w[ c d ] ].each do |(a, b)|
      puts 'a=%s b=%s' % [ a, b ]
    end
    

    这在情况更复杂的情况下很有用:
    [ %w[ a b ], %w[ c d ] ].each_with_index do |(a, b), i|
      puts 'a=%s b=%s @ %d' % [ a, b, i ]
    end
    

    因为在这种情况下,它遍历数组和附加的另一个元素,所以每一项实际上都是内部%w[ a b ], 0形式的元组,如果您的块仅接受一个参数,则它将转换为数组。

    这与定义变量时可以使用的原理大致相同:
    a, b = %w[ a b ]
    a
    # => 'a'
    b
    # => 'b'
    

    实际上,这为ab分配了独立的值。与:
    a, b = [ %w[ a b ] ]
    a
    # => [ 'a', 'b' ]
    b
    # => nil
    

    10-07 13:23
    查看更多