我想成为世界级的软件开发者。现在读大学三年级。欢迎发E-mail与我讨论关于软件开发的各种想法。 我的新blog在http://redworld.blog.ubuntu.org.cn/

Ruby1.9的变化(一) - 新的语法和语意

上一篇 / 下一篇  2008-01-25 01:07:33 / 个人分类:Ruby

查看( 89 ) / 评论( 4 )
资料来自:http://eigenclass.org/hiki.rb?Changes+in+Ruby+1.9

文中有实验性标记的说明很可能会在短时间内被拿掉,原文中解释为”crazy ideas“。
最近将持续连载翻译Ruby1.9的变化。

新的语法和语意

新的字面量hash语法[Ruby2]

CODE:

{a: "foo"}                # => {:a=>"foo"}代码块局部变量 [实验性]

如下使用:

CODE:

# {normal args一般参数; 局部变量local variables}
d = 2
a = lambda{|;d| d = 1}
a.call()
d                # => 2
当一个变量被隐藏时,Ruby1.9会给出一个警告:

CODE:

-:2: warning: shadowing outer local variable - d代码块参数的作用域总是在代码块内

CODE:

a = 1
10.times{|a| } # !> shadowing outer local variable - a 代码块外的局部变量a被隐藏
a                                                 # => 1
新的lambdas语法 [非常实验性]

CODE:

a = ->(b,c){ b + c }
a.call(1,2) # => 3
注意这里没有说是替换目前传统的代码块语法。Matz已经明确说明了后者会永远有效。新的语法允许为代码块参数指定默认值,如

CODE:

{|a,b=1| ... } 这种语法在目前的基于bison的Ruby解析器LALR是不能实现的.

这种新语法可以不用括号包裹参数:

CODE:

-> { }.call # => nil
-> a, b  { a + b }.call(1,2) # => 3
c = 1; -> a, b; c  { c = a + b }.call(1,2); c # => 1
还可以更加诡异地使用:

CODE:

c = 2; -> ;c { c = 1 }.call; c # => 2甚至是

CODE:

c = 2; -> *d ; c { d }.call(1,2,3) # => [1, 2, 3]
c = 2; -> ; c { c = 1 }.call; c # => 2
用.()替代使用call方法或者[]方法来调用Procs[实验性]

现在可以这样做:

CODE:

a = lambda{|*b| b}
a.(1,2)                # => [1, 2]
注意你需要句点:

CODE:

a = lambda{|*b| b}
a(1,2)                # =>
               #           (eval):2: syntax error...
               #                         (a)(1,2)...
~> -:2: undefined method `a' for main:Object (NoMethodError)
可以在括号内使用任何表达式:

CODE:

(lambda{|a,b| a + b}).(1,2)                # => 3
.()用法会无视接受者而调用其call方法:

CODE:

"foo".(1,2)   # ~>  undefined method `call' for "foo":String (NoMethodError)Block arguments代码块参数

代码块可以使用&block参数:

CODE:

define_method(:foo){|&b| b.call(bar)}ruby-dev:23533

新的代码块参数语意

|v|现在会像|v,|的形式工作:

CODE:

[RUBY_VERSION, RUBY_RELEASE_DATE]                 # => ["1.8.5", "2006-08-25"]
def m; yield 1, 2; end
m{|v| v}                                          # => [1, 2] # !> multiple values for a block parameter (2 for 1)
相对应的:

CODE:

[RUBY_VERSION, RUBY_RELEASE_DATE]                 # => ["1.9.0", "2007-08-03"]
def m; yield 1, 2; end
m{|v| v}                                          # => 1
to_splat 方法使用*参数
用to_splat方法代替to_a方法

nil.to_splat 返回 [].

允许多个*操作符

经Audrey Tang建议,Ruby1.9允许在方法调用是使用多个*操作符

CODE:

   def foo(*a)
     a
   end
   
   foo(1, *[2,3], 4, *[5,6])                        # => [1, 2, 3, 4, 5, 6]
表达式也是:

CODE:

[RUBY_VERSION, RUBY_RELEASE_DATE]                # => ["1.9.0", "2007-08-03"]
a = [1,2,3]
b = [4,5,6]
[*a, *b]                                         # => [1, 2, 3, 4, 5, 6]
允许在可选参数后加上必要参数

ruby-dev:29014

CODE:

   def m(a, b=nil, *c, d)
     [a,b,c,d]
   end
   m(1,2)                                         # => [1, nil, [], 2]
?c的语意

?a现在返回一个单字符字符串代替原来的整数值:

CODE:

?a   # => "a"[] 方法的参数

可以在[]方法中使用星号,"assocs"(不用方括号的hash)和代码块参数:

CODE:

   RUBY_VERSION                                       # => "1.9.0"
   RUBY_RELEASE_DATE                                  # => "2006-06-11"
   class Foo; def [](*a, &block); block.call(a) end end
   
   a = (0..3).to_a
   Foo.new[*a, :op => :+]{|x| x }                     # => [0, 1, 2, 3, {:op=>:+}]
printf风格的格式化字符串(%)
%c 可以输出单字符字符串
%u 为负数提供类似%d的格式 (ruby-core:11575)

允许三元运算符( ? : )扩展到新行

CODE:

p 1 == 2 ?
   0
   :
   1
# >> 1
ruby-dev:29189

defined?方法和局部变量

CODE:

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
相对应的:

CODE:

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
[ 本帖最后由 maninred 于 2008-1-25 01:17 编辑 ]

TAG:

red_world maninred 发布于2008-01-25 01:13:46
ruby1.9的下一个版本会在2月份发布,Matz在ruby-talk中有提到。
Xavier on Rails xavier 发布于2008-01-25 14:33:07
我已经感受到1.9速度的飞升了~
内容还没怎么体验
dreamwinter发布于2008-01-31 13:40:00
不太适应啊,不过个人比较关注Lambda语法的改变
red_world maninred 发布于2008-01-31 16:19:11

QUOTE:

原帖由 dreamwinter 于 08/1/31 13:40 发表
不太适应啊,不过个人比较关注Lambda语法的改变
可以看看http://www.infoq.com/cn/news/2008/01/new-lambda-syntax
我来说两句

(可选)

日历

« 2009-01-08  
    123
45678910
11121314151617
18192021222324
25262728293031

数据统计

  • 访问量: 1600
  • 日志数: 63
  • 书签数: 3
  • 建立时间: 2007-10-09
  • 更新时间: 2008-02-15

RSS订阅

Open Toolbar