Главная
Блог разработчиков phpBB
 
+ 17 предустановленных модов
+ SEO-оптимизация форума
+ авторизация через соц. сети
+ защита от спама

Чего нам ожидать от Ruby 2.1?

Anna | 20.06.2014 | нет комментариев
Несколько дней назад Константин Хаасе, один из ключевых людей в сообществе Ruby, опубликовал запись в своём блоге, посвящённую анонсу заблаговременной версии Ruby 2.1. Изменений между версиями 2.0 и 2.1 накопилось довольно, Дабы вчитаться в его изложение, и отменнее — на русском языке.

NB: разумеется, Ruby 2.1 содержит все восхитительные вероятности предыдущей версии — 2.0. Метаморфозы предыдущих версий упоминаться не будут.

Механизм уточнений

Вестимо, что в Ruby 2.0 введён механим уточнений. Реализация данного механизма оказалась довольно двойственной, следственно в версии 2.0 его функциональность была несколько ограничена и помечена как экспериментальная.

Стоит напомнить, что уточнения разрешают использовать манки патчи в рамках исключительного Ruby-файла:

module Foo
  refine String do
    def foo
      self   "foo"
    end
  end
end

using Foo
puts "bar".foo

За пределами данного файла экземпляры класса String не будут отвечать на способ foo.

В новой версии Ruby уточнения не будут являться экспериментальной вероятностью. Больше того, их дозволено будет использовать не только к области видимости верхнего яруса, но и к отдельным модулям.

module Foo
  refine String do
    def foo
      self   "foo"
    end
  end
end

module Bar
  using Foo
  puts "bar".foo
end

Значимо иметь в виду, что Непомерное пристрастие уточнениями может привести к написанию довольно запутанного кода. Разработчики некоторых реализаций Ruby теснее заявили, что могут отказаться поддерживать уточнения.

Десятичные литералы

При работе с Ruby дозволено подметить, что значения с плавающей запятой ведут себя не лучшим образом, когда над ними выполняются вычисления, привычные по работе с десятичными дробями:

irb(main):001:0> 0.1 * 3
=> 0.30000000000000004

Сходственное поведение приводит к тому, что огромное число Ruby-разработчиков начинает применять целые числа, имитируя заданное число знаков позже запятой при представлении итога. Безоговорочно, такой метод работает отлично при сурово заданном числе знаков позже запятой. В отвратном случае доводится применять разумные дроби — это не дюже нехорошо, но язык не владеет довольно комфортным синтаксисом для работы с ними.

Новая версия Ruby представляет суффикс r для изложения десятичных и разумных дробей:

irb(main):001:0> 0.1r
=> (1/10)
irb(main):002:0> 0.1r * 3
=> (3/10)

Иммутабельные строки

Если в коде содержится объявление строки, то всякий раз при исполнении содержащей его строки кода Ruby создаёт новейший объект класса String. Это обусловлено мутабельностью строк. В таких случаях символыведут себя значительно результативнее, так как инициализируются каждого один раз. Тем не менее, для сопоставления символа со строкой необходимо провести реформирование строки в символ либо символа в строку. Выполнение таких реформирований — опасная операция, открывающую потенциальную вероятность для DoS-атаки, так как символы не освобождаются при сборке мусора, а всякое реформирование символа в строку создаёт новую строку.

Исключительный метод уберечь себя от отрицательных последствий в данном случае — беречь и применять строку как константу:

class Foo
  BAR = "bar"

  def bar?(input)
    input == BAR
  end
end

Зачастую, Дабы избавиться от мутабельности, исполняют заморозку строки. Заморозка объекта предотвращает его метаморфоза со стороны кода на Ruby, впрочем не даёт никаких прибавок к продуктивности:

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

В приведённом коде будет сделан иммутабельный объект класса String, и где бы он не применялся — он будет инициализирован каждого один раз.

Не исключено, что такой синтаксис может показаться необычным. Тот же самый фрагмент кода дозволено переписать равнозначно:

class Foo
  def bar?(input)
    input == %q{bar}f
  end
end

Вообще, вопрос использования суффикса f к массивам и хэшам остаётся открытым.

Непременные ключевые доводы

Отчего-то в анонсе Ruby 2.0 не были упомянуты непременные ключевые доводы. Выходит, Ruby 2.0 представляет непременные ключевые доводы:

def foo(a: 10)
  puts a
end

foo(a: 20) # 20
foo        # 10

При таком подходе к объявлению способов доводится указывать значения доводов по-умолчанию. Это не неизменно допустимо, следственно 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

Сейчас это поведение изменилось и имя способа возвращается как символ:

def foo() end # => :foo

Это пригодно при метапрограммировании и выполнении сходственных трюков. Скажем, все ли знают, что способ private может принимать доводы?

# приватным будет только способ foo
class Foo
  def foo
  end

  private :foo

  # способ bar останется незатронутым
  def bar
  end
end

Сейчас, когда def возвращает имя объявленного способа, дозволено легко делать способы приватными:

# приватными будут только способы foo и bar
class Foo
  private def foo
  end

  private 
  def bar
  end

  def baz
  end
end

Удаление лишних байт из строк

Сейчас Ruby имеет комфортный способ для удаление лишних байт из строк:

some_string.scrub("")

Прежде было трудно добиться идентичного поведения такого способа для всех существующих реализаций Ruby, следственно также доступна библиотека для этого.

StringScanner поддерживает именованные захваты

Многим нравится класс StringScanner из стандартной библиотеки языка. В частности, он применяется в Rails для разбора образцов маршрутов. То же самое будет делать Sinatra 2.0.

В версии 1.9 была добавлена помощь именованных захватов, впрочем StringScanner их не поддерживал:

require 'strscan'
s = StringScanner.new("foo")
s.scan(/(?<bar>.*)/)
puts s[:bar]

В Ruby 2.0 такой код выкинет исключение:

TypeError: no implicit conversion of Symbol into Integer

Но при запуске на Ruby 2.1 всё будет отлично:

foo

Работа с сетевыми интерфейсами

Сейчас дозволено получить доступ к сетевыми и

Источник: programmingmaster.ru

Оставить комментарий
Форум phpBB, русская поддержка форума phpBB
Рейтинг@Mail.ru 2008 - 2017 © BB3x.ru - русская поддержка форума phpBB