天天看点

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做参数咯。

   define_method :foo lambda{|&b| b.call("hello")}

t=test.new

t.foo do |b|

   puts b    => hello

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

8、允许数组多重展开

def foo(*a)

     a

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

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]

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联合使用,例如下面的例子:

   def [](*a)

     puts a.inspect

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、打印字符,打印字符和负数,

  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)"

vs.

ruby_version                                      # => "1.9.0"

ruby_release_date                                 # => "2007-08-03"

  defined? i                                      # => "local-variable"

文章转自庄周梦蝶  ,原文发布时间 2008-10-01