当前位置:  开发笔记 > 后端 > 正文

Ruby块采用数组或多个参数

如何解决《Ruby块采用数组或多个参数》经验,为你挑选了2个好方法。

今天我很惊讶地发现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,"

我原以为最后两个例子会出现某种错误.

    这是红宝石中更一般概念的一个例子吗?

    我不认为我的问题开头的措辞是正确的,我怎么称呼这里发生的事情?

akuhn.. 6

Ruby块像这样古怪.

规则是这样的,如果一个块接受多个参数并且它产生一个响应的对象,to_ary那么该对象被扩展.这使得产生一个数组而不是产生一个元组似乎对于带有两个或更多参数的块的行为方式相同.

yield [a,b]yield a,b当块接受一个参数或仅当块采用可变数目的参数做虽然有所不同.

让我证明这两点

def yield_tuple
  yield 1, 2, 3
end

yield_tuple { |*a| p a }
yield_tuple { |a| p [a] }
yield_tuple { |a, b| p [a, b] }
yield_tuple { |a, b, c| p [a, b, c] }
yield_tuple { |a, b, c, d| p [a, b, c, d] } 

版画

[1, 2, 3]
[1] 
[1, 2]
[1, 2, 3]
[1, 2, 3, nil]

def yield_array
  yield [1,2,3]
end

yield_array { |*a| p a }
yield_array { |a| p [a] }
yield_array { |a, b| p [a, b] }
yield_array { |a, b, c| p [a, b, c] }
yield_array { |a, b, c, d| p [a, b, c, d] }

版画

[[1, 2, 3]]
[[1, 2, 3]] 
[1, 2] # array expansion makes it look like a tuple
[1, 2, 3] # array expansion makes it look like a tuple
[1, 2, 3, nil] # array expansion makes it look like a tuple

最后要表明Ruby中的所有内容都使用duck-typing

class A
  def to_ary
    [1,2,3]
  end
end

def yield_arrayish
  yield A.new
end

yield_arrayish { |*a| p a }
yield_arrayish { |a| p [a] }
yield_arrayish { |a, b| p [a, b] }
yield_arrayish { |a, b, c| p [a, b, c] }
yield_arrayish { |a, b, c, d| p [a, b, c, d] }

版画

[#]
[#]
[1, 2] # array expansion makes it look like a tuple
[1, 2, 3] # array expansion makes it look like a tuple
[1, 2, 3, nil] # array expansion makes it look like a tuple

PS,相同的数组扩展行为适用于proc行为类似于块的lambda闭包,而闭包的行为类似于方法.



1> akuhn..:

Ruby块像这样古怪.

规则是这样的,如果一个块接受多个参数并且它产生一个响应的对象,to_ary那么该对象被扩展.这使得产生一个数组而不是产生一个元组似乎对于带有两个或更多参数的块的行为方式相同.

yield [a,b]yield a,b当块接受一个参数或仅当块采用可变数目的参数做虽然有所不同.

让我证明这两点

def yield_tuple
  yield 1, 2, 3
end

yield_tuple { |*a| p a }
yield_tuple { |a| p [a] }
yield_tuple { |a, b| p [a, b] }
yield_tuple { |a, b, c| p [a, b, c] }
yield_tuple { |a, b, c, d| p [a, b, c, d] } 

版画

[1, 2, 3]
[1] 
[1, 2]
[1, 2, 3]
[1, 2, 3, nil]

def yield_array
  yield [1,2,3]
end

yield_array { |*a| p a }
yield_array { |a| p [a] }
yield_array { |a, b| p [a, b] }
yield_array { |a, b, c| p [a, b, c] }
yield_array { |a, b, c, d| p [a, b, c, d] }

版画

[[1, 2, 3]]
[[1, 2, 3]] 
[1, 2] # array expansion makes it look like a tuple
[1, 2, 3] # array expansion makes it look like a tuple
[1, 2, 3, nil] # array expansion makes it look like a tuple

最后要表明Ruby中的所有内容都使用duck-typing

class A
  def to_ary
    [1,2,3]
  end
end

def yield_arrayish
  yield A.new
end

yield_arrayish { |*a| p a }
yield_arrayish { |a| p [a] }
yield_arrayish { |a, b| p [a, b] }
yield_arrayish { |a, b, c| p [a, b, c] }
yield_arrayish { |a, b, c, d| p [a, b, c, d] }

版画

[#]
[#]
[1, 2] # array expansion makes it look like a tuple
[1, 2, 3] # array expansion makes it look like a tuple
[1, 2, 3, nil] # array expansion makes it look like a tuple

PS,相同的数组扩展行为适用于proc行为类似于块的lambda闭包,而闭包的行为类似于方法.



2> tadman..:

Ruby的块函数对它们有一个怪癖,即如果你在包含数组的东西上进行迭代,你可以将它们扩展为不同的变量:

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

使用时,这种模式是非常有用的Hash#each,你想打出来的key,并value在对部分: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'

这实际上是为a和分配独立的价值观b.对比:

a, b = [ %w[ a b ] ]
a
# => [ 'a', 'b' ]
b
# => nil


@mbigras大多数语言都称之为"解构",ES6现在拥有它,LISP(http://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node252.html),clojure(http: //blog.jayfields.com/2010/07/clojure-destructuring.html)以及更多.
推荐阅读
wangtao
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有