2013-03-11 106 views
0

我试图了解在使用block编写代码时管道内部的局部变量创建(|)。并且在我的IRB以下代码中也尝试过。ruby​​中`| x,y |`和`| x; y = 0 |`有什么区别?

[1,2,3].each {|x;y| y=x; print y} 

#123=> [1, 2, 3] 
[1,2,3].each {|x;y = 0| y=x; print y} 

#SyntaxError: (irb):1: syntax error, unexpected '=', expecting '|' 
#[1,2,3].each {|x;y = 0| y=x; print y} 
        ^
#(irb):1: syntax error, unexpected '}', expecting $end 
#  from C:/Ruby193/bin/irb:12:in `<main>' 

但不明白发生了什么事与第二代码,而第一个是完美的。

谁能告诉我|x,y| and |x;y=0|之间的区别?希望这个 问题的答案对我有意义。

再下面我完美的作品:

a = "hello world".split(//).each{ |x,newstr = Array.new() | newstr = x.capitalize;puts newstr } 

#H 
#E 
#L 
#L 
#O 
# 
#W 
#O 
#R 
#L 
#D 
#=> ["h", "e", "l", "l", "o", " ", "w", "o", "r", "l", "d"] 

回答

4

在Ruby 1.9开始不接受的值,它可以通过将;与块参数分开来在块中声明局部变量。在你的例子中,x是一个块参数,而y是一个局部变量。下面的代码很好地说明了它。

> [1,2,3].each {|x; y| puts "x: #{x} - y: #{y}"} 
x: 1 - y: 
x: 2 - y: 
x: 3 - y: 
=> [1, 2, 3] 

由于y未初始化,因此没有值。 从句法上讲,不能像在第二个示例中那样在管道| |之间直接初始化本地块变量。这是被禁止的。

但是,在Ruby 1.9中,您可以设置块参数的默认值。的确,

> [1,2,3].each {|x,y=0| puts "x: #{x} - y: #{y}"} 
x: 1 - y: 0 
x: 2 - y: 0 
x: 3 - y: 0 
=> [1, 2, 3] 

在语法上是正确的。这一次y是一个块参数,默认值为0。你可以用下面的图解说明不同之处:

> { one: 1, two: 2, three: 3}.each {|x,y=0| puts "x: #{x} - y: #{y}"} 
x: one - y: 1 
x: two - y: 2 
x: three - y: 3 
=> {:one=>1, :two=>2, :three=>3} 
+0

请参阅我的更新。那么为什么我们能够在'|'中初始化数组对象呢? – 2013-03-11 10:43:05

+0

看到我的答案,你可以设置参数块的默认值,而不是'||'之间的局部变量块。这就是为什么你最后的例子是有效的。 – toch 2013-03-11 10:44:13

+0

好吧!这意味着'方法'也是阻止的,它允许默认值语法,但匿名块不允许。 – 2013-03-11 10:47:46

1

;y被用来解决Ruby的作用域(阴影外部变量),因为它里面||

+0

我知道,但是我的问题是''y = 0'和''y'在'|'里面有什么区别。查看我的更新说明。 – 2013-03-11 10:38:49

+0

这只是Ruby禁止的。 – Ven 2013-03-11 10:39:54

相关问题