Ruby 1.9概要(1)新的语法和语义
一、新的语法和语义
1、新的Hash定义语法:
例如{a:2} 等价于 {:a=>2}
但是 {"a":2} 出错,并不等价于 {:"a"=>2}
2、试验性质的block内的局部变量
在1.8,block的与外部同名的变量是同一个变量,也就是说block内的变量也可以修改外部的同名变量,这很容易形成难以查找的bug。
例子:
#
{常规参数;局部变量}
d
=
2
a
=
lambda
{
|
;d
|
d
=
1
}
a.call()
d
#
=> 2
注意到,分号后的d是block局部变量。
3、block的参数现在都是局部变量
4、新lambda语法,试验性质:
->
a,b {a
+
b}.call(
1
,
2
)
=>
3
一些比较诡异的写法:
->
{ }.call
#
=> nil
->
a, b { a
+
b }.call(
1
,
2
)
#
=> 3
c
=
1
;
->
a, b; c { c
=
a
+
b }.call(
1
,
2
); c
#
=> 1(注意这里,;号的c是block的局部变量,因此c=1在lambda调用前后
没有改变。)
5、 .()的调用方式
过去
lambda
{
|*
d
|
d}.call(
1
,
2
,
3
)
现在可以简化为
lambda
{
|*
d
|
d}.(
1
,
2
,
3
)
.()这样的方式都将调用接受者的call方法,无论接收者是什么,例如:
"
foo
"
.(
1
,
2
)
#
~> undefined method `call' for "foo":String (NoMethodError)
显然,这个方式另一种形式上的method_missing,比如在类中应用:
class
Test
def
self.call(
*
d)
d
end
end
Test.(
1
,
2
,
3
)
=>
[
1
,
2
,
3
]
这个特性也是试验性质
6、block可以使用&block做参数咯。
例子:
class
Test
define_method :foo
lambda
{
|&
b
|
b.call(
"
hello
"
)}
end
t
=
Test.new
t.foo do
|
b
|
puts b
=>
hello
end
7、新的block参数语义,|v| 现在等价于 |v,|
还是通过例子吧:
1.8:
def
m;
yield
1
,
2
; end
m{
|
v
|
v}
#
=> [1, 2]
#
!> multiple values for a block parameter (2 for 1)
1.9:
def
m;
yield
1
,
2
; end
m{
|
v
|
v}
#
=> 1
8、允许数组多重展开
def
foo(
*
a)
a
end
foo(
1
,
*
[
2
,
3
],
4
,
*
[
5
,
6
])
#
=> [1, 2, 3, 4, 5, 6]
a
=
[
1
,
2
,
3
]
b
=
[
4
,
5
,
6
]
[
*
a,
*
b]
#
=> [1, 2, 3, 4, 5, 6]
9、可选参数后允许再有强制参数的存在,这在过去是不允许的。例如下面的代码在1.8是错误的,而1.9却可以正常运行:
def
foo(a,b
=
"
test
"
,c)
puts c
end
foo(
1
)
=>
wrong number of arguments(
1
for
2
)
foo(
1
,
2
)
=>
2
foo(
1
,
3
)
=>
3
foo(
1
,
2
,
3
)
=>
3
更复杂的:
def
m(a, b
=
nil,
*
c, d)
[a,b,c,d]
end
m(
1
)
=>
error
m(
1
,
2
)
=>
[
1
,nil,[],
2
]
m(
1
,
2
,
3
)
=>
[
1
,
2
,[],
3
]
m(
1
,
2
,
3
,
4
)
=>
[
1
,
2
,[
3
],
4
]
m(
1
,
2
,
3
,
4
,
5
)
=>
[
1
,
2
,[
3
,
4
],
5
]
m(
1
,
2
,
3
,
4
,
5
,
6
]
=>
[
1
,
2
,[
3
,
4
,
5
],
6
]
10、?c的语义,过去?+字符返回字符的ascii码整数,现在返回字符"c"
例如:
?a
=>
97
(
1.8
)
?a
=>
"
a
"
(
1.9
)
11、[]方法的参数现在可以将数组和hash联合使用,例如下面的例子:
class
Test
def
[](
*
a)
puts a.inspect
end
end
a
=
[
1
,
2
,
3
]
Test.new[
*
a,:a
=>
2
]
=>
SyntaxERROR:compire error (
1.8
)
Test.new[
*
a,:a
=>
2
]
=>
[
1
,
2
,
3
,{:a
=>
2
}] (
1.9
)
12、打印字符,打印字符和负数,
1.8
:
printf
"
%c
"
,
"
a
"
=>
can
'
t convert String into Integer
printf
"
%u
"
,
-
1
=>
..
4294967295
1.9
:
printf
"
%c
"
,
"
a
"
=>
a
printf
"
%u
"
,
-
1
=>
-
1
13、defined?方法和local variable:
RUBY_VERSION
#
=> "1.8.5"
RUBY_RELEASE_DATE
#
=> "2006-08-25"
a
=
0
defined? a
#
=> "local-variable"
1
.times do
|
i
|
defined? i
#
=> "local-variable(in-block)"
end
VS.
RUBY_VERSION
#
=> "1.9.0"
RUBY_RELEASE_DATE
#
=> "2007-08-03"
a
=
0
defined? a
#
=> "local-variable"
1
.times do
|
i
|
defined? i
#
=> "local-variable"
end