庄周梦蝶

生活、程序、未来
   :: 首页 ::  ::  :: 聚合  :: 管理

Ruby 1.9概要(1)新的语法和语义

Posted on 2008-10-01 13:37 dennis 阅读(761) 评论(0)  编辑  收藏 所属分类: 动态语言

一、新的语法和语义
1、新的Hash定义语法:
例如{a:2}  等价于 {:a=>2}
但是 {"a":2} 出错,并不等价于 {:"a"=>2}

2、试验性质的block内的局部变量
在1.8,block的与外部同名的变量是同一个变量,也就是说block内的变量也可以修改外部的同名变量,这很容易形成难以查找的bug。
例子:
# {常规参数;局部变量}
= 2
= 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
= 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 12; end
m{
|v| v}                                          # => [1, 2]
                                                  # !> multiple values for a block parameter (2 for 1)
1.9:
def m; yield 12; end
m{
|v| v}                                          # => 1

8、允许数组多重展开
def foo(*a)
     a
end
foo(
1*[2,3], 4*[5,6])                        # => [1, 2, 3, 4, 5, 6]

= [1,2,3]
= [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"
= 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"
= 0
defined? a                                        
# => "local-variable"
1.times do |i|
  defined? i                                      
# => "local-variable"
end


只有注册用户登录后才能发表评论。


网站导航: