Pull to refresh

Новые возможности ruby 2.3.0 preview 1

Недавно был анонсирован Ruby 2.3.0 preview 1 который включает в себя несколько новых функций.

Неизменяемые строки (frozen string)


В ruby 3.0 планируются сделать все строки не изменяемыми (frozen) по умолчанию, что принесет большие трудности при переходе на эту версию. На данный момент в ruby можно сделать строку не изменяемой если использовать Object#freeze. Преимущества таких строк в том, что они требуют меньше памяти.

В ruby 2.3.0 была добавлена специальная директива frozen_string_literal, которая делает все строки не изменяемыми по умолчанию, что позволит облегчить переход в будущем на версию 3.0.

# frozen_string_literal: true
text = '123'
text << '456'
puts text

ruby string.rb
>> string.rb:3:in `<main>': can't modify frozen String (RuntimeError)

Или вместо директивы можно использовать аргумент --enable-frozen-string-literal.

text = '123'
text << '456'
puts text

ruby --enable-frozen-string-literal string.rb
>> string.rb:3:in `<main>': can't modify frozen String (RuntimeError)

Также был добавлен аргумент --enable-frozen-string-literal-debug, который покажет какой объект подвергся изменению, что даст больше информации при отладке.

# frozen_string_literal: true
text = '123'
text << '456'
puts text

Отображается номер строки где изменяется строка и также, в какой строке объект был первоначально создан.

ruby --enable-frozen-string-literal-debug string.rb
>>string.rb:3:in `<main>': can't modify frozen String, created at string.rb:2 (RuntimeError)


Safe navigation operator


Разработчики работающие с ruby on rails наверняка знают метод object#try, try(:method_name) проверят существует ли метод название которого передано в качестве первого аргумента, возвращает значение метода или nil, исключая выброс NoMethodError.

Ruby 2.3.0 включает новый оператор &. который работает также как object#try из ActiveSupport.

class Person
  attr_accessor :account

  def initialize
    @name = 'Dima'
  end

  def first_name
    name
  end

  def check_account
    @account = Account.new
  end
end

class Account
  attr_accessor :money
  def initialize
    @money = 100
  end
end

person = Person.new
puts "Money: #{person&.account&.money}"

Выведет Money:

person = Person.new
person.check_account
puts "Money: #{person&.account&.money}"

Выведет Money: 100

Did you mean


did_you_mean.gem был включен в новую версию ruby и служит для облегчения отладки приложения при возникновение ошибок NameError и NoMethodError.

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

class Person
  def initialize
    @name = ‘Dima’
  end

  def first_name
    name
  end
end

Ошибка в имени класса.

person = Persson.new

Выведет:

person.rb:11:in `<main>': uninitialized constant Persson (NameError)
Did you mean?  Person

Ошибка в название метода.

person = Person.new
person.first_nam

Выведет:

person.rb:12:in `<main>': undefined method `first_nam' for #<Person:0x007fa31397b8b0 @name="Dima"> (NoMethodError)
Did you mean?  first_name

Ошибка в типе переменной.

person = Person.new
person.first_name

Выведет:

Person.rb:7:in `first_name': undefined local variable or method `name' for #<Person:0x007fc21917b8c0 @name="Dima"> (NameError)
Did you mean?  @name

Основное изменение которое может существенно сломать совместимость между версиями это конечно же frozen string, так что уже сейчас нужно начать это учитывать, чтобы обеспечить безболезненный переход на ruby 3.0.
Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.