Novos recursos no Ruby 2.3 e 2.4
É bom ficar a par dos novos recursos de idioma que ajudarão seu jogo de golfe. Existem alguns ótimos nos últimos Rubies.
Ruby 2.3
O operador de navegação segura: &.
Quando você chama um método que pode retornar, nil
mas deseja encadear chamadas de método adicionais, caso contrário, desperdiça bytes manipulando o nil
caso:
arr = ["zero", "one", "two"]
x = arr[5].size
# => NoMethodError: undefined method `size' for nil:NilClass
x = arr[5].size rescue 0
# => 0
O "operador de navegação segura" interrompe a cadeia de chamadas de método se alguém retornar nil
e retornar nil
para toda a expressão:
x = arr[5]&.size || 0
# => 0
Array#dig
& Hash#dig
Acesso profundo a elementos aninhados, com um belo nome abreviado:
o = { foo: [{ bar: ["baz", "qux"] }] }
o.dig(:foo, 0, :bar, 1) # => "qux"
Retorna nil
se atingir um beco sem saída:
o.dig(:foo, 99, :bar, 1) # => nil
Enumerable#grep_v
O inverso de - Enumerable#grep
retorna todos os elementos que não correspondem ao argumento fornecido (comparado com ===
). Por exemplo grep
, se um bloco é fornecido, seu resultado é retornado.
(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
Retorna um Proc que gera o valor para a chave fornecida, o que pode ser bastante útil:
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
O Ruby 2.4 ainda não saiu, mas em breve estará disponível e possui alguns ótimos recursos. (Quando for lançado, atualizarei esta postagem com alguns links para os documentos.) Aprendi sobre a maioria delas nesta excelente postagem no blog .
Enumerable#sum
Não mais arr.reduce(:+)
. Agora você pode apenas fazer arr.sum
. É necessário um argumento opcional de valor inicial, cujo padrão é 0 para elementos numéricos ( [].sum == 0
). Para outros tipos, você precisará fornecer um valor inicial. Também aceita um bloco que será aplicado a cada elemento antes da adição:
[[1, 10], [2, 20], [3, 30]].sum {|a,b| a + b }
# => 66
Integer#digits
Isso retorna uma matriz de dígitos de um número na ordem do menor para o maior:
123.digits # => [3, 2, 1]
Comparado com, digamos 123.to_s.chars.map(&:to_i).reverse
, isso é muito bom.
Como bônus, é necessário um argumento radix opcional:
a = 0x7b.digits(16) # => [11, 7]
a.map{|d|"%x"%d} # => ["b", "7"]
Comparable#clamp
Faz o que diz na lata:
v = 15
v.clamp(10, 20) # => 15
v.clamp(0, 10) # => 10
v.clamp(20, 30) # => 20
Como está no Comparable, você pode usá-lo com qualquer classe que inclua Comparable, por exemplo:
?~.clamp(?A, ?Z) # => "Z"
String#unpack1
Economia de 2 bytes em relação a .unpack(...)[0]
:
"👻💩".unpack(?U) # => [128123]
"👻💩".unpack(?U)[0] # => 128123
"👻💩".unpack1(?U) # => 128123
Argumento de precisão para Numeric#ceil
, floor
etruncate
Math::E.ceil(1) # => 2.8
Math::E.floor(1) # => 2.7
(-Math::E).truncate(1) # => -2.7
Atribuição múltipla em condicionais
Isso gera um erro nas versões anteriores do Ruby, mas é permitido na 2.4.
(a,b=1,2) ? "yes" : "no" # => "yes"
(a,b=nil) ? "yes" : "no" # => "no"