Cайт веб-разработчика, программиста Ruby on Rails ESV Corp. Екатеринбург, Москва, Санкт-Петербург, Новосибирск, Первоуральск

Админка на Ruby on Rails

Новое в Ruby 2.1

Хотя релиз 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:

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.