Ruby1.9的变化(一) - 新的语法和语意
资料来自:http://eigenclass.org/hiki.rb?Changes+in+Ruby+1.9
文中有实验性标记的说明很可能会在短时间内被拿掉,原文中解释为”crazy ideas“。
最近将持续连载翻译Ruby1.9的变化。
新的语法和语意
新的字面量hash语法[Ruby2]
-
{a: "foo"} # => {:a=>"foo"}
代码块局部变量 [实验性]
如下使用:
# {normal args一般参数; 局部变量local variables} d = 2 a = lambda{|;d| d = 1} a.call() d # => 2
当一个变量被隐藏时,Ruby1.9会给出一个警告:
-
-:2: warning: shadowing outer local variable - d
代码块参数的作用域总是在代码块内
-
a = 1
-
10.times{|a| } # !> 代码块外的局部变量a被隐藏
-
a # => 1
新的lambdas语法 [非常实验性]
-
{|a,b=1| ... }
这种语法在目前的基于bison的Ruby解析器LALR是不能实现的.
这种新语法可以不用括号包裹参数:
-
-> { }.call # => nil
-
-> a, b { a + b }.call(1,2) # => 3
-
c = 1; -> a, b; c { c = a + b }.call(1,2); c # => 1
还可以更加诡异地使用:
-
c = 2; -> ;c { c = 1 }.call; c # => 2
甚至是
-
c = 2; -> *d ; c { d }.call(1,2,3) # => [1, 2, 3]
-
c = 2; -> ; c { c = 1 }.call; c # => 2
用.()替代使用call方法或者[]方法来调用Procs[实验性]
现在可以这样做:
-
a = lambda{|*b| b}
-
a.(1,2) # => [1, 2]
注意你需要句点:
-
a = lambda{|*b| b}
-
a(1,2) # =>
-
# (eval):2: syntax error...
-
# (a)(1,2)...
-
~> -:2: undefined method `a' for main:Object (NoMethodError)
可以在括号内使用任何表达式:
-
(lambda{|a,b| a + b}).(1,2) # => 3
.()用法会无视接受者而调用其call方法:
-
"foo".(1,2)
-
# ~> undefined method `call' for "foo":String (NoMethodError)
Block arguments代码块参数
代码块可以使用&block参数:
-
define_method(:foo){|&b| b.call(bar)}
ruby-dev:23533
新的代码块参数语意
|v|现在会像|v,|的形式工作:
-
[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)
相对应的:
-
[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允许在方法调用是使用多个*操作符
-
def foo(*a)
-
a
-
end
-
-
foo(1, *[2,3], 4, *[5,6]) # => [1, 2, 3, 4, 5, 6]
表达式也是:
-
[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]
允许在可选参数后加上必要参数
-
def m(a, b=nil, *c, d)
-
[a,b,c,d]
-
end
-
m(1,2) # => [1, nil, [], 2]
?c的语意
?a现在返回一个单字符字符串代替原来的整数值:
-
?a # => "a"
[] 方法的参数
可以在[]方法中使用星号,"assocs"(不用方括号的hash)和代码块参数:
-
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)
允许三元运算符( ? : )扩展到新行
p 1 == 2 ? 0 : 1 # >> 1
ruby-dev:29189
defined?方法和局部变量
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
相对应的:
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