Respostas:
É chamado de Operador de Navegação Segura. Introduzido no Ruby 2.3.0, permite chamar métodos em objetos sem se preocupar que o objeto possa ser nil(Evitando um undefined method for nil:NilClasserro), semelhante ao trymétodo no Rails .
Então você pode escrever
@person&.spouse&.name
ao invés de
@person.spouse.name if @person && @person.spouse
Dos documentos :
my_object.my_methodIsso envia a mensagem my_method para my_object. Qualquer objeto pode ser um receptor, mas, dependendo da visibilidade do método, o envio de uma mensagem pode gerar um NoMethodError.
Você pode usar &. para designar um receptor, então my_method não é chamado e o resultado é nulo quando o receptor é nulo. Nesse caso, os argumentos de my_method não são avaliados.
Nota: Embora o @Santosh tenha dado uma resposta clara e completa, gostaria de adicionar um pouco mais de background e uma nota importante sobre seu uso com variáveis que não são de instância.
É chamado de " Operador de Navegação Segura " ( também conhecido como "Operador de encadeamento opcional", "Operador nulo-condicional" etc. ). Matz parece chamá-lo de "operador solitário". Foi introduzido no Ruby 2.3 . Ele envia um método para um objeto apenas se não estiver nil.
# Call method `.profile` on `user` only if `user` is not `nil`
@user&.profile
# Equivalent to
unless @user.nil?
@user.profile
end
Observe que o código acima usa variáveis de instância. Se você deseja usar um operador de navegação seguro com variáveis locais, deverá verificar se suas variáveis locais estão definidas primeiro.
# `user` local variable is not defined previous
user&.profile
# This code would throw the following error:
NameError: undefined local variable or method `user' for main:Object
Para corrigir esse problema, verifique se sua variável local está definida primeiro ou defina-a como nulo:
# Option 1: Check the variable is defined
if defined?(user)
user&.profile
end
# Option 2: Define your local variable. Example, set it to nil
user = nil
user&.profile # Works and does not throw any errors
O Rails possui um trymétodo que basicamente faz o mesmo. Ele usa o sendmétodo internamente para chamar um método. Matz sugeriu que é lento e esse deve ser um recurso de idioma interno.
Muitas outras linguagens de programação têm características semelhantes: Objective C, Swift, Python, Scala, CoffeeScript, etc. No entanto, uma sintaxe comum é ?.(ponto de interrogação). Mas, essa sintaxe não pôde ser adotada pelo Ruby. Como ?foi permitido nos nomes dos métodos e, portanto, a ?.sequência de símbolos já é um código Ruby válido. Por exemplo:
2.even?.class # => TrueClass
É por isso que a comunidade Ruby teve que criar uma sintaxe diferente. Foi uma discussão activa e diferentes opções foram consideradas ( .?, ?, &&, etc.). Aqui está uma lista de algumas considerações:
u.?profile.?thumbnails
u\profile\thumbnails
u!profile!thumbnails
u ? .profile ? .thumbnails
u && .profile && .thumbnails
# And finally
u&.profile&.thumbnails
Ao escolher a sintaxe, os desenvolvedores analisaram diferentes casos extremos e a discussão é bastante útil. Se você deseja passar por todas as variantes e nuances do operador, consulte a discussão sobre introdução de recursos no rastreador oficial de problemas do Ruby.
.?e outras opções foram consideradas, mas &.foram escolhidas! Então, só &.vai funcionar.
&.e não.? , meu mal. Atualizei minha resposta. Obrigado pela atenção!
user.?profiledeveria ser user&.profile(não poderia editá-lo eu mesmo, pois é apenas uma edição de 1 caractere!).
Seja cauteloso! Embora o operador de navegação seguro seja conveniente, também pode ser fácil enganar-se a mudar sua lógica com ele. Eu recomendo evitar o uso dele no controle de fluxo. Exemplo:
str = nil
puts "Hello" if str.nil? || str.empty?
# The above line is different than the below line
puts "Hello" if str&.empty?
No primeiro exemplo, str.nil? retorna truee str.empty?nunca é chamado, fazendo com que a putsinstrução seja executada. No segundo exemplo, no entanto, str&.empty?retorna nilfalse, e a putsinstrução nunca é executada.
str.nil?seja verdadeira (como você diz), o que significa str.empty?que na verdade não será chamado (é assim que o ||operador funciona). O restante da sua declaração está correto.
puts "hello" unless str&.present?(trilhos só para o presente método?)
usado para verificação nula, como em kotlin e swift Por exemplo; com Objeto -> Swift e Kotlin
model = car?.model
esse modelo pode ser nulo (Swift) ou nulo (Kotlin) se não tivermos definido o valor do modelo na classe de carro. usamos esse e comercial em vez de ponto de interrogação em rubi
model = car&.model
se usar car.model sem e comercial e se o modelo for nulo, o sistema não poderá continuar em execução.
try!método, nãotry