답변:
안전 탐색 연산자라고합니다. Ruby 2.3.0에서 도입 된이 객체를 사용하면 Rails 의 메소드 와 유사하게 오브젝트가 오류가 발생 nil
하는 것을 걱정하지 않고 오브젝트에서 메소드를 호출 할 수 있습니다.undefined method for nil:NilClass
try
.
그래서 당신은 쓸 수 있습니다
@person&.spouse&.name
대신에
@person.spouse.name if @person && @person.spouse
로부터 문서 :
my_object.my_method
그러면 my_method 메시지가 my_object로 전송됩니다. 모든 객체는 수신자가 될 수 있지만 메소드의 가시성 메시지에 따라 NoMethodError가 발생할 수 있습니다.
&를 사용할 수 있습니다. 수신자를 지정하기 위해 my_method가 호출되지 않고 수신자가 nil이면 결과는 nil입니다. 이 경우 my_method의 인수는 평가되지 않습니다.
참고 : @Santosh가 명확하고 완전한 대답을했지만 배경 지식을 더 추가하고 인스턴스가 아닌 변수와의 사용에 관한 중요한 참고 사항을 추가하고 싶습니다 .
" 안전 내비게이션 연산자 "( "선택적 체인 연산자", "무조건 연산자"등 )라고합니다. Matz는 이것을 "고독한 연산자"라고 부릅니다. 그것은 한 루비 2.3에 도입 . 메소드가 아닌 경우에만 메소드를 오브젝트에 보냅니다 nil
.
# Call method `.profile` on `user` only if `user` is not `nil`
@user&.profile
# Equivalent to
unless @user.nil?
@user.profile
end
위의 코드는 인스턴스 변수를 사용합니다. 로컬 변수와 함께 안전한 탐색 연산자를 사용하려면 로컬 변수가 먼저 정의되어 있는지 확인해야합니다.
# `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
이 문제를 해결하려면 로컬 변수가 먼저 정의되어 있는지 확인하거나 nil로 설정하십시오.
# 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
Rails에는 try
기본적으로 동일한 방법이 있습니다. send
내부적으로 메소드를 사용하여 메소드를 호출합니다. Matz 는 속도가 느리고 이것이 내장 언어 기능이어야한다고 제안 했습니다.
Objective C, Swift, Python, Scala, CoffeeScript 등 다른 많은 프로그래밍 언어도 비슷한 기능을 가지고 있습니다. 그러나 일반적인 구문은 ?.
(물음표)입니다. 그러나이 구문은 Ruby에서 채택 할 수 없습니다. 때문에 ?
메소드 이름 허용함으로써하고, ?.
심볼 시퀀스는 이미 유효한 루비 코드이다. 예를 들면 다음과 같습니다.
2.even?.class # => TrueClass
그렇기 때문에 Ruby 커뮤니티는 다른 구문을 사용해야했습니다. 그것은 적극적인 토론이었고, 다른 옵션은 (간주되었다 .?
, ?
, &&
, 등). 다음은 몇 가지 고려 사항 목록입니다.
u.?profile.?thumbnails
u\profile\thumbnails
u!profile!thumbnails
u ? .profile ? .thumbnails
u && .profile && .thumbnails
# And finally
u&.profile&.thumbnails
구문을 선택하는 동안 개발자는 다양한 엣지 사례를 살펴 보았으며 토론은 매우 유용합니다. 운영자의 모든 변형과 뉘앙스를 살펴보고 싶다면 공식 Ruby 문제 추적기에 대한 이 기능 소개 토론 을 참조하십시오 .
.?
다른 옵션도 고려되었지만 &.
선택되었습니다! 따라서 &.
작동합니다.
&.
아니라 .?
나의 나쁜. 내 답변을 업데이트했습니다. 고마워요!
user.?profile
가 있습니다 user&.profile
.
조심하세요! 안전한 내비게이션 연산자는 편리하지만 논리를 변경하도록 쉽게 속일 수 있습니다. 흐름 제어에 사용하지 않는 것이 좋습니다. 예:
str = nil
puts "Hello" if str.nil? || str.empty?
# The above line is different than the below line
puts "Hello" if str&.empty?
첫 번째 예에서는 str.nil?
반환 true
되고 str.empty?
호출되지 않으므로 puts
명령문이 실행됩니다. 그러나 두 번째 예에서는 false를 str&.empty?
반환 nil
하고 puts
명령문은 실행되지 않습니다.
str.nil?
사실이지만 ( str.empty?
실제로 말하면) 실제로 호출되지는 않습니다 ( ||
연산자가 작동하는 방식). 나머지 진술은 정확합니다.
puts "hello" unless str&.present?
(현재? 방법에 대해서만 레일)
try!
방법이 아니라 작동합니다try