Refinements позволяют применять "monkey patches" только в единственном файле Ruby:
module Foo
refine String do
def foo
self + "foo"
end
end
end
using Foo
puts "bar".foo #=> barfoo
Вне этого файла в String по прежнему нет метода foo.
В Ruby 2.1, refinements уже не эксперементальный механизм и может быть использован также внутри модуля (module) без влияния на глобальное пространство имен в самом файле.
module Foo
refine String do
def foo
self + "foo"
end
end
end
module Bar
using Foo
puts "bar".foo #=> barfoo
end
Следует обратить внимание на то, что использование refinements может привести к тому, что получается очень запутывающий код, и поэтому, разработчики предыдущих реализаций Ruby уже указали на что, что они вряд ли будут использовать этот механизм.
Десятичные литералы (Decimal Literals)
Вам, должно быть известно, что числа с плавающей запятой (floats) далеки от идеала при выполнении вычислений с числами с фиксированной десятичной точкой:
0.1 * 3 #=> 0.30000000000000004
Многие разработчики Ruby используют фиксированную точность (количество знаков после запятой) при отображении результата. Однако, это работает хорошо, только если Вы действительно работаете с числами с фиксированной десятичной точкой. В противном случае Вы должны использовать рациональные величины. Совсем не плохо, за исключением того, что не было никакого приемлемого синтаксиса для них (за исключением изменения возвращаемого значения метода Integer#/).
В Ruby 2.1 вводится суффикс r для decimal/rational литералов:
0.1r #=> (1/10)
0.1r * 3 #=> (3/10)
"Замороженные" строковые литералы
Когда в Вашем коде появляется строковый литерал, Ruby создает новый строковый литерал каждый раз, когда строка кода выполняется. Это происходит потому, что строки в Ruby непостоянны. Это объясняет, почему обозначения (symbol) более эффективны во многих случаях. Однако, обозначения не строки. Например, если Вы хотите сравнить некоторый ввод данных пользователем с обозначением, Вы должны или преобразовать символ в строку, или строку к обозначению. Это означает, что Вы либо открываете свой код для атаки "отказ в обслуживании", поскольку обозначения не обработаны сборщиком "мусора", либо снова расходуются ресурсы на создание строк.
Один из способов состоит в том, чтобы сохранить строку в константе и затем использовать эту константу вместо строкового литерала:
class Foo
BAR = "bar"
def bar?(input)
input == BAR
end
end
Сейчас для предотвращения изменения строкового литерала применяется "заморозка", но к сожалению это не дает преимущества в производительности:
class Foo
BAR = "bar".freeze
def bar?(input)
input == BAR
end
end
Это может стать утомительным. К счастью, Ruby 2.1 представляет синтаксис, делающий что-то эквивалентное "под капотом" (автоматически):
class Foo
def bar?(input)
input == "bar"f
end
end
Это код создаст "замороженный" строковый объект один раз и затем снова использует его каждый раз, когда код выполняется.
Вероятно, может показаться, что этот синтаксис выглядит несколько странно. Обоснование заключается в том, что это работает как суффикс для десятичного числа, объясненный выше. Есть прием, который позволяет оформить код несколько иначе:
class Foo
def bar?(input)
input == %q{bar}f
end
end
Хотя этот вариант мне лично кажется еще более корявым.
Есть нерешенный вопрос, предлагающий добавить этот суффикс также к массивам и хешам.
Обязательные именованные аргументы
В Ruby 2.0 были добавлены именованные аргументы методов. Однако, именованные аргументы всегда должны иметь значение по умолчанию, соответственно, могут быть пропущены при вызове метода. В Ruby 2.1 теперь возможно указать обязательные именованные аргументы:
def foo(a:)
puts a
end
foo(a: 20) #=> 20
foo # ArgumentError: missing keyword: a
Определение метода возвращает имя метода
В предыдущих версиях Ruby, определение метода с помощью def возвращает nil:
def foo() end #=> nil
В Ruby 2.1 сейчас возвращается наименование метода в виде обозначения (symbol):
def foo() end #=> :foo
Это полезно для метапрограммирования и других подобных техник. Например, Вы знали, что private также может быть вызван с параметрами?
# только foo будет закрытым методом
class Foo
def foo
end
private :foo
# bar по прежнему будет открытым
def bar
end
end
Теперь, когда определение метода возвращает имя, это может использоваться, чтобы сделать единственный метод закрытым:
# только foo и bar будут закрытыми
class Foo
private def foo
end
private \
def bar
end
def baz
end
end
Удаление "мусорных" байтов из строк
Ruby теперь обладает удобным методом, чтобы удалить "байты мусора" из строк:
some_string.scrub("")
Доступ к сетевым интерфейсам
Теперь возможно получить доступ к сетевым интерфейсам через Socket.getifaddrs:
require 'socket'
Socket.getifaddrs.each do | i |
puts "#{i.name}: #{i.addr.ip_address}" if i.addr.ip?
end
Более быстрые числа для серьезной математики
Ruby 2.1 теперь быстрее, когда дело доходит до больших чисел, поскольку используются 128-битные целые числа. Получено дополнительное увеличение скорости при помощи библиотеки GNU Multiple Precision Arithmetic Library.
Хотя релиз Ruby 2.1 еще не выпущен, а лишь планируется 25.12.2013, но уже известны новые возможности, улучшения, изменения в синтаксисе.
25.12.2013 как всегда точно в срок был выпущен релиз Ruby 2.1.0
Естественно, Ruby 2.1 сохраняет все новшества Ruby 2.0.
Refinements
(refinement – усовершенствование, улучшение)
Механизм Refinements был добавлен в Ruby 2.0, но функциональность была ограничена, и механизм был определен как экспериментальный.
Refinements позволяют применять "monkey patches" только в единственном файле Ruby:
Вне этого файла в
String
по прежнему нет методаfoo
.В Ruby 2.1, refinements уже не эксперементальный механизм и может быть использован также внутри модуля (
module
) без влияния на глобальное пространство имен в самом файле.Следует обратить внимание на то, что использование refinements может привести к тому, что получается очень запутывающий код, и поэтому, разработчики предыдущих реализаций Ruby уже указали на что, что они вряд ли будут использовать этот механизм.
Десятичные литералы (Decimal Literals)
Вам, должно быть известно, что числа с плавающей запятой (floats) далеки от идеала при выполнении вычислений с числами с фиксированной десятичной точкой:
Многие разработчики Ruby используют фиксированную точность (количество знаков после запятой) при отображении результата. Однако, это работает хорошо, только если Вы действительно работаете с числами с фиксированной десятичной точкой. В противном случае Вы должны использовать рациональные величины. Совсем не плохо, за исключением того, что не было никакого приемлемого синтаксиса для них (за исключением изменения возвращаемого значения метода
Integer#/
).В Ruby 2.1 вводится суффикс r для decimal/rational литералов:
"Замороженные" строковые литералы
Когда в Вашем коде появляется строковый литерал, Ruby создает новый строковый литерал каждый раз, когда строка кода выполняется. Это происходит потому, что строки в Ruby непостоянны. Это объясняет, почему обозначения (
symbol
) более эффективны во многих случаях. Однако, обозначения не строки. Например, если Вы хотите сравнить некоторый ввод данных пользователем с обозначением, Вы должны или преобразовать символ в строку, или строку к обозначению. Это означает, что Вы либо открываете свой код для атаки "отказ в обслуживании", поскольку обозначения не обработаны сборщиком "мусора", либо снова расходуются ресурсы на создание строк.Один из способов состоит в том, чтобы сохранить строку в константе и затем использовать эту константу вместо строкового литерала:
Сейчас для предотвращения изменения строкового литерала применяется "заморозка", но к сожалению это не дает преимущества в производительности:
Это может стать утомительным. К счастью, Ruby 2.1 представляет синтаксис, делающий что-то эквивалентное "под капотом" (автоматически):
Это код создаст "замороженный" строковый объект один раз и затем снова использует его каждый раз, когда код выполняется.
Вероятно, может показаться, что этот синтаксис выглядит несколько странно. Обоснование заключается в том, что это работает как суффикс для десятичного числа, объясненный выше. Есть прием, который позволяет оформить код несколько иначе:
Хотя этот вариант мне лично кажется еще более корявым.
Есть нерешенный вопрос, предлагающий добавить этот суффикс также к массивам и хешам.
Обязательные именованные аргументы
В Ruby 2.0 были добавлены именованные аргументы методов. Однако, именованные аргументы всегда должны иметь значение по умолчанию, соответственно, могут быть пропущены при вызове метода. В Ruby 2.1 теперь возможно указать обязательные именованные аргументы:
Определение метода возвращает имя метода
В предыдущих версиях Ruby, определение метода с помощью
def
возвращаетnil
:В Ruby 2.1 сейчас возвращается наименование метода в виде обозначения (
symbol
):Это полезно для метапрограммирования и других подобных техник. Например, Вы знали, что
private
также может быть вызван с параметрами?Теперь, когда определение метода возвращает имя, это может использоваться, чтобы сделать единственный метод закрытым:
Удаление "мусорных" байтов из строк
Ruby теперь обладает удобным методом, чтобы удалить "байты мусора" из строк:
Доступ к сетевым интерфейсам
Теперь возможно получить доступ к сетевым интерфейсам через
Socket.getifaddrs
:Более быстрые числа для серьезной математики
Ruby 2.1 теперь быстрее, когда дело доходит до больших чисел, поскольку используются 128-битные целые числа. Получено дополнительное увеличение скорости при помощи библиотеки GNU Multiple Precision Arithmetic Library.