25/10/2012
2 ноября вышла первая версия Ruby 2.0. По плану, 24 февряля 2013 года выйдет 2.0.0-p0, что значит — релиз, но пока не для продакшна.
Даты выхода
- Начало декабря: 2.0.0-preview2
- После нового года: 2.0.0-rc1
- Начало февраля: 2.0.0-rc2
- 24 февраля: 2.0.0-p0
Новое в 2.0.0
- Refinements
- Keyword arguments
- Enumerator#lazy
- Module#prepend
- Converting convention to Hash: #to_h
- %i: a literal for symbol array
- Новый движок регулярных выражений — Onigmo
- Поддержка DTrace (будет в версии preview2)
- Импорт/экспорт байткода
- Стандартные библиотеки станут гемами
- Переход на UTF
Refinements
Давайте рассмотрим следующий кусок кода:
module NumberQuery
refine String do
def number?
match(/^[1-9][0-9]+$/) ? true : false
end
end
end
И попробуем вызвать его:
begin
"123".number?
rescue => e
p e #=> #<NoMethodError: undefined method `number?' for "123":String>
end
Этот метод недоступен в глобальном пространстве, но его можно использовать внутри модуля NumberQuery:
module NumberQuery
p "123".number? # => true
end
Так-же этот метод можно добавить в другой модуль:
module MyApp
using NumberQuery
p "123".number? # => true
p "foo".number? # => false
end
Keyword arguments
Новая фича простая, но очень удобная, это как новые хеши в 1.9, к которым я до сих пор не могу привыкнуть и использую старый вид :)
def wrap(string, before: "<", after: ">")
"#{before}#{string}#{after}" # в теле как переменная,
# в параметрах как хеш
end
# опциональное использование
p wrap("foo") # => "<foo>"
# один или другой
p wrap("foo", before: "#<") # => "#<foo>"
p wrap("foo", after: "]") # => "<foo]"
# порядок не важен
p wrap("foo", after: "]", before: "[") # => "[foo]"
# две звезды для захвата всех аргументов
# или использование аргументов в виде хеша
def capture(**opts)
opts
end
p capture(foo: "bar") # => {:foo=>"bar"}
# ключи можно использовать как символы
opts = {:before => "(", :after => ")"}
p wrap("foo", **opts) # => "(foo)"
# можно использовать старый вид хешей
p wrap("foo", :before => "{", :after => "}") # => "{foo}"
Module#prepend
Тоже очень полезное нововведение, комментарии и объяснения излишне.
module A
def foo
"A"
end
end
class B
include A
def foo
"B"
end
end
p B.new.foo # => "B"
class C
prepend A
def foo
"B"
end
end
p C.new.foo # => "A"
Converting convention to Hash: #to_h
def foo(opts)
raise ArgumentError, "opts must be a Hash" unless opts.is_a?(Hash)
# do stuff with opts
end
Теперь можно добавить универсальности:
def foo(options)
if options.respond_to?(:to_h)
opts = options.to_h
else
raise TypeError, "can't convert #{options.inspect} into Hash"
end
# do stuff with opts
end
%i: a literal for symbol array
p %i{hurray huzzah whoop} # => [:hurray, :huzzah, :whoop]
Установка и тестирование новой версии (ruby-2.0.0-preview1)
Этот кусок статьи не мой, его я нагло позаимствовал у Александрова Игоря :)
Железо:
- OS: OSX 10.8.2
- CPU: 2.2GHz i7
- RAM: 8Gb 1333 MHz DDR3
- HHD: Seagate Momentus XT, 2.5”, SATA 3Gb/s, 7200 rpm, hybrid
Установка:
$ export CC=clang # http://bugs.ruby-lang.org/issues/7264
$ rvm install ruby-2.0.0-preview1
Результаты тестирования: