Ruby 2.0一览

[复制链接]
查看11 | 回复9 | 2014-2-19 11:55:14 | 显示全部楼层 |阅读模式
With Ruby 2.0 set to be released on February 24th, exactly on the 20th anniversary of Ruby’s first debut, I decided to write this article to give you a quick rundown of some of the most interesting changes. And if you would like to experiment with this version before the official release, you can do so by following the instructions in this article.
Installing RC1
Ruby 2.0 has deprecated the use of syck in favor of psych, and YAML is now completely dependent on libyaml. This means that we must install this library before installing Ruby 2.0.
On any *nix based system, we can install it by downloading the source package and manually building it:
1
$ wget http://pyyaml.org/download/libyaml/yaml-0.1.4.tar.gz
2
[
DISCUZ_CODE_2
]nbsp;tar xzvf yaml-0.1.4.tar.gz
3
[
DISCUZ_CODE_2
]nbsp;cd yaml-0.1.4
4
$ ./configure
5
[
DISCUZ_CODE_2
]nbsp;make
6
[
DISCUZ_CODE_2
]nbsp;make install复制代码
Or if you are on a Mac, you can install it with homebrew:
1
$ brew update
2
$ brew install libyaml复制代码


回复

使用道具 举报

千问 | 2014-2-19 11:55:14 | 显示全部楼层
Once libyaml is installed, we can go ahead and install RC1 using rvm:1
$ rvm install ruby-2.0.0-rc1复制代码Next, we need to tell rvm to use this new Ruby version:1
$ rvm use ruby-2.0.0-rc1复制代码Great, we are now ready to dive into the changes.
回复

使用道具 举报

千问 | 2014-2-19 11:55:14 | 显示全部楼层
Once libyaml is installed, we can go ahead and install RC1 using rvm:1
$ rvm install ruby-2.0.0-rc1复制代码Next, we need to tell?rvm?to use this new Ruby version:1
$ rvm use ruby-2.0.0-rc1复制代码Great, we are now ready to dive into the changes.
回复

使用道具 举报

千问 | 2014-2-19 11:55:14 | 显示全部楼层
Changes
The changes introduced in 2.0 are pretty extensive, but in this article I will be focusing mainly on the following:
1 Refinements
2 Keyword Arguments
3 Module#prepend
4 Enumerable#lazy
5 Language Changes
回复

使用道具 举报

千问 | 2014-2-19 11:55:14 | 显示全部楼层
Refinements (Experimental)
Refinements are set to replace unsafe monkey-patching by providing a better, safer, and isolated way to patch code. Traditionally, when a patch is applied, it modifies the object globally – whether you like it or not. With refinements, you can limit monkey-patching to certain scopes.
Let us look at a concrete monkey-patching example. Say we wanted to extend the String class and add a bang method that adds an exclamation point after the given string. We would do something like this:1
class String
2
def bang
3
"#{self}!"
4
end
5
end复制代码This change is now global. Which means that any string that calls .bang will behave as such:1
> "hello".bang
2
#=> "hello!"复制代码
回复

使用道具 举报

千问 | 2014-2-19 11:55:14 | 显示全部楼层
顶一下


回复

使用道具 举报

千问 | 2014-2-19 11:55:14 | 显示全部楼层
To prevent this global scope change, refinement was proposed. It works by utilizing two new methods: Module#refine and main.using. The first, is a block that allows for locally-scoped monkey patching. And the latter, imports refinements into the current file or eval string, so that it can be used in other places.
Taking our previous example, this is how we can safely extend the String class using refinements:1
module StringBang
2
refine String do
3
def bang
4
"#{self}!"
5
end
6
end
7
end
复制代码Now, if we try to call .bang on any string, it will fail:1
> "hello".bang
2
#=> NoMethodError: undefined method `bang' for "":String
复制代码
回复

使用道具 举报

千问 | 2014-2-19 11:55:14 | 显示全部楼层
This is because the change to the String class is contained within the StringBangmodule. After we import this refinement with the using keyword, it works as expected:1
> using StringBang
2
> "hello".bang
3
#=> "hello!"复制代码WARNING: This feature is still experimental and the behavior may change in future versions of Ruby. Charles Nutter of JRuby has a great explanation of the challenges presented with this.

回复

使用道具 举报

千问 | 2014-2-19 11:55:14 | 显示全部楼层
Keyword Arguments
Also known as named parameters, this feature is pretty useful, as it allows a method to be declared to receive keyword arguments. This is used by many languages, and it is finally integrated into Ruby.
In the old way, if you wanted to accept keyword arguments, you would have to fake it by receiving a hash argument in a method:1
def config(opts={}); end复制代码And if you had default values, you would then merge the user-supplied arguments on top of your default values:1
def config(opts={})
2
defaults = {enabled: true, timeout: 300}
3
opts = defaults.merge(opts)
4
end复制代码It sure works but it is a hack, and I am sure we have all used it in one way or another.

回复

使用道具 举报

千问 | 2014-2-19 11:55:14 | 显示全部楼层
Forget this old way and say hello to the true keyword arguments in Ruby 2.0. Using the same example as above, here is how we can define our config method in the new way:1
def config(enabled: true, timeout: 300)
2
[enabled, timeout]
3
end
复制代码Now, let us see the different ways in which we can invoke this method:1
> config() #no args
2
#=> [true, 300]
3
> config(enabled: false) #only enabled
4
#=> [false, 300]
5
> config(timeout: 20) #only timeout
6
#=> [true, 20]
7
> config(timeout: 10, enabled: false) #inverse order
8
#=> [false, 10]
复制代码
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题

0

回帖

4882万

积分

论坛元老

Rank: 8Rank: 8

积分
48824836
热门排行