一、新的语法和语义
1、新的Hash定义语法:
例如{a:2} 等价于 {:a=>2}
但是 {"a":2} 出错,并不等价于 {:"a"=>2}
2、试验性质的block内的局部变量
在1.8,block的与外部同名的变量是同一个变量,也就是说block内的变量也可以修改外部的同名变量,这很容易形成难以查找的bug。
例子:
注意到,分号后的d是block局部变量。
3、block的参数现在都是局部变量
4、新lambda语法,试验性质:
一些比较诡异的写法:
5、 .()的调用方式
过去
现在可以简化为
.()这样的方式都将调用接受者的call方法,无论接收者是什么,例如:
显然,这个方式另一种形式上的method_missing,比如在类中应用:
class Test
def self.call( * d)
d
end
end
Test.( 1 , 2 , 3 ) => [ 1 , 2 , 3 ] 这个特性也是试验性质
6、block可以使用&block做参数咯。
例子:
7、新的block参数语义,|v| 现在等价于 |v,|
还是通过例子吧:
1.8:
8、允许数组多重展开
9、可选参数后允许再有强制参数的存在,这在过去是不允许的。例如下面的代码在1.8是错误的,而1.9却可以正常运行:
10、?c的语义,过去?+字符返回字符的ascii码整数,现在返回字符"c"
例如:
11、[]方法的参数现在可以将数组和hash联合使用,例如下面的例子:
12、打印字符,打印字符和负数,
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
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 = 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调用前后 没有改变。)
-> 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
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:
m{ | v | v} # => [1, 2]
# !> multiple values for a block parameter (2 for 1)
def
m;
yield
1
,
2
; end
m{ | v | v} # => 1
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]
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
更复杂的:
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 ]
[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 )
?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 )
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:
printf " %c " , " a " => can ' t convert String into Integer
printf " %u " , - 1 => .. 4294967295
1.9 :
printf " %c " , " a " => a
printf " %u " , - 1 => - 1
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
文章转自庄周梦蝶 ,原文发布时间 2008-10-01