Новые функции в Ruby 2.3 и 2.4
Хорошо быть в курсе новых языковых функций, которые помогут вашей игре в гольф. В последних рубинах есть несколько замечательных.
Ruby 2.3
Оператор безопасной навигации: &.
Когда вы вызываете метод, который может возвращать, nil
но вы хотите связать дополнительные вызовы метода, если это не так, вы тратите впустую байты, обрабатывая nil
случай:
arr = ["zero", "one", "two"]
x = arr[5].size
# => NoMethodError: undefined method `size' for nil:NilClass
x = arr[5].size rescue 0
# => 0
«Оператор безопасной навигации» останавливает цепочку вызовов методов, если возвращается nil
и возвращается nil
для всего выражения:
x = arr[5]&.size || 0
# => 0
Array#dig
& Hash#dig
Глубокий доступ к вложенным элементам с красивым коротким именем:
o = { foo: [{ bar: ["baz", "qux"] }] }
o.dig(:foo, 0, :bar, 1) # => "qux"
Возвращает, nil
если попадает в тупик:
o.dig(:foo, 99, :bar, 1) # => nil
Enumerable#grep_v
Обратный Enumerable#grep
-returns всех элементов , которые не соответствуют данному аргументу ( по сравнению с ===
). Например grep
, если дан блок, вместо него возвращается результат.
(1..10).grep_v 2..5 # => [1, 6, 7, 8, 9, 10]
(1..10).grep_v(2..5){|v|v*2} # => [2, 12, 14, 16, 18, 20]
Hash#to_proc
Возвращает Proc, который возвращает значение для данного ключа, что может быть очень удобно:
h = { N: 0, E: 1, S: 2, W: 3 }
%i[N N E S E S W].map(&h)
# => [0, 0, 1, 2, 1, 2, 3]
Ruby 2.4
Ruby 2.4 еще не выпущен, но он скоро появится и имеет несколько замечательных небольших функций. (Когда он выйдет, я дополню этот пост некоторыми ссылками на документы.) О большинстве из них я узнал из этого замечательного поста в блоге .
Enumerable#sum
Нет больше arr.reduce(:+)
. Теперь вы можете просто сделать arr.sum
. Он принимает необязательный аргумент начального значения, который по умолчанию равен 0 для числовых элементов ( [].sum == 0
). Для других типов вам необходимо указать начальное значение. Он также принимает блок, который будет применен к каждому элементу перед добавлением:
[[1, 10], [2, 20], [3, 30]].sum {|a,b| a + b }
# => 66
Integer#digits
Это возвращает массив цифр числа в порядке наименьшей значимости:
123.digits # => [3, 2, 1]
По сравнению, скажем 123.to_s.chars.map(&:to_i).reverse
, это довольно мило.
В качестве бонуса он принимает необязательный аргумент radix:
a = 0x7b.digits(16) # => [11, 7]
a.map{|d|"%x"%d} # => ["b", "7"]
Comparable#clamp
Делает то, что говорит на банке:
v = 15
v.clamp(10, 20) # => 15
v.clamp(0, 10) # => 10
v.clamp(20, 30) # => 20
Поскольку он находится в Comparable, вы можете использовать его с любым классом, который включает Comparable, например:
?~.clamp(?A, ?Z) # => "Z"
String#unpack1
2-байтовая экономия более .unpack(...)[0]
:
"👻💩".unpack(?U) # => [128123]
"👻💩".unpack(?U)[0] # => 128123
"👻💩".unpack1(?U) # => 128123
Точность аргумент Numeric#ceil
, floor
иtruncate
Math::E.ceil(1) # => 2.8
Math::E.floor(1) # => 2.7
(-Math::E).truncate(1) # => -2.7
Многократное присваивание в условных выражениях
Это вызывает ошибку в более ранних версиях Ruby, но допускается в 2.4.
(a,b=1,2) ? "yes" : "no" # => "yes"
(a,b=nil) ? "yes" : "no" # => "no"