閱讀423 返回首頁    go 阿裏雲 go 技術社區[雲棲]


Ruby 1.9概要(1)新的語法和語義

一、新的語法和語義
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
文章轉自莊周夢蝶  ,原文發布時間 2008-10-01

最後更新:2017-05-18 11:01:45

  上一篇:go  Ruby 1.9概要(2)Kernel和Object
  下一篇:go  《Spring 5 官方文檔》1. Spring入門指南(二)