Ruby에서 조건부 연산자 (? :)를 어떻게 사용합니까?


303

? :Ruby에서 조건부 연산자 ( ) 는 어떻게 사용됩니까?

예를 들어, 이것이 맞습니까?

<% question = question.size > 20 ? question.question.slice(0, 20)+"..." : question.question %>

1
그렇습니다, 나는 생각하지만, 또한 당신이 그것을 달성 할 수 있다고 생각합니다 : question=question[0,20] 그것이 20보다 작다면, 그것은 변하지 않을 것입니다.
DGM

길이가 20보다 큰 경우 나 또한 '...'는를 추가 할 필요가
Mithun Sreedharan

1
주어진 열에서 맹목적으로 줄을 잘리지 않도록주의하십시오. 중간에 단어를 자른 다음 줄임표 ( '...')를 추가하면 나빠질 수 있습니다. 대신 문장 부호 나 공백 문자를 찾아서 잘립니다. 근처에 더 나은 중단 점이없는 경우에만 단어 중간을 잘라야합니다.
Tin Man

답변:


496

그것은 인 삼원 연산자 및는 (괄호가 필요하지 않은) C처럼 작동한다. 다음과 같이 작동하는 표현식입니다.

if_this_is_a_true_value ? then_the_result_is_this : else_it_is_this

그러나 Ruby에서는 우선 순위 문제를 제외하고 === if식이기도합니다 . 둘 다 표현입니다.if a then b else c enda ? b : c

예 :

puts (if 1 then 2 else 3 end) # => 2

puts 1 ? 2 : 3                # => 2

x = if 1 then 2 else 3 end
puts x                        # => 2

첫 번째 경우 괄호가 필요합니다 (그렇지 않으면 Ruby는 puts if 1추가 정크 가 있다고 생각하기 때문에 혼란 스럽 습니다). 그러나 마지막 문제에서는 언급되지 않았으므로 필요하지 않습니다.

여러 줄에서 가독성을 높이기 위해 "long-if"형식을 사용할 수 있습니다.

question = if question.size > 20 then
  question.slice(0, 20) + "..."
else 
  question
end

0을 넣습니까? 2 : 3은 결과적으로 2를 제공합니다. 왜 그런 겁니까?
X_Trust

18
@X_Trust Ruby에서 유일한 잘못된 값은 nilfalse입니다. 실제로는 그리 평범하지 않습니다.
Kroltan

35
puts true ? "true" : "false"
=> "true"


puts false ? "true" : "false"
=> "false"

간결하지만 그 일을 설명합니다.
Tin Man

4
puts (true ? "true" : "false")괄호로 작은 편집 . 그렇지 않으면 작업 순서가 명확하지 않습니다. 내가 이것을 처음 읽었을 때 나는 그것을 읽었을 때 혼란스러워졌고 부울을 반환 (puts true) ? "true" : "false"할 것으로 예상 puts되어 문자열 값이되었습니다.
Fresheyeball

26

ERB를 사용하면 Rails에 있음을 알 수 있습니다. 그렇다면, truncate당신을 위해 일을 해줄 내장 된 도우미 를 고려 하십시오 :

<% question = truncate(question, :length=>30) %>

대단해! 내가 정확히하고 싶은 것 !!
Mithun Sreedharan

11
이것은 몇 년 늦었지만 모든 구문 적 측면을 뛰어 넘고 질문자가 성취하려고하는 것에 바로 갔기 때문에이 답변에 매우 감동했습니다.
Mike Buckbee

2
+1이지만 erb는 반드시 레일을 의미하지는 않습니다 (Sinatra, 독립형 ERB 등).
폭스 윌슨

17

@pst는 큰 대답을했지만 루비에서는 삼항 연산자가 Perl 및 C와 달리 여러 줄에 쓸 수있는 구문이 정확하도록 한 줄에 작성되었다는 것을 언급하고 싶습니다.

(true) ? 1 : 0

일반적으로 루비는 여러 줄로 나누려고 할 때 오류를 발생 시키지만 \줄 끝에 줄 연속 기호를 사용할 수 있으며 루비는 행복 할 것입니다.

(true)   \
  ? 1    \
  : 0

이것은 간단한 예이지만 코드를 깔끔하게 배치하기 때문에 더 긴 줄을 다룰 때 매우 유용 할 수 있습니다.

연산자를 마지막 줄에 두어 줄 연속 문자없이 삼항을 사용할 수도 있지만 마음에 들지 않거나 권장하지는 않습니다.

(true) ?
  1 :
  0

조건부 테스트 및 / 또는 결과가 길어질수록 코드를 읽는 것이 실제로 어렵다고 생각합니다.

혼란 스럽기 때문에 삼항 연산자를 사용하지 말라고 언급 한 의견을 읽었으므로 무언가를 사용하지 않는 나쁜 이유입니다. 같은 논리로 정규 표현식, 범위 연산자 ( ' ..'및 알 수없는 "플립 플롭"변형)를 사용해서는 안됩니다 . 올바르게 사용하면 강력하므로 올바르게 사용하는 법을 배워야합니다.


왜 괄호를 넣었 true습니까?

OP의 예를 고려하십시오.

<% question = question.size > 20 ? question.question.slice(0, 20)+"..." : question.question %>

조건부 테스트를 래핑하면 테스트가 시각적으로 분리되므로 더 읽기 쉽습니다.

<% question = (question.size > 20) ? question.question.slice(0, 20)+"..." : question.question %>

물론, 공백을 합리적으로 추가하여 전체 예제를 훨씬 더 읽기 쉽게 만들 수 있습니다. 이것은 테스트되지 않았지만 아이디어를 얻습니다.

<% question = (question.size > 20) ? question.question.slice(0, 20) + "..." \
                                   : question.question 
%>

또는 더 관용적으로 쓰면 :

<% question = if (question.size > 20)
                question.question.slice(0, 20) + "..."
              else 
                question.question 
              end
%>

가독성도 나빠진다는 주장은 쉬운 일 question.question이다.


1
여러 줄로 구성된 경우 if ... else ... end를 사용하지 않는 이유는 무엇입니까?
Wayne Conrad

1
Perl과 C에서 일한지 너무 오랜 세월 때문에? 상황과 상황이 시각적으로 더 명확한 지 여부에 따라 둘 중 하나를 사용합니다. 때때로 / else가 너무 장황한 경우가 있습니까?
Tin Man

1
이 경우 @WayneConrad는 적어도 하나의 문제는이 답변에 설명 : stackoverflow.com/a/4252945/2597260는 여러 경우를 사용하는 몇 가지 방법 / 삼항 연산자 비교 : gist.github.com/nedzadarek/0f9f99755d42bad10c30
Darek Nędza

왜 괄호를 넣었 true습니까?
Zac

1
true실제로 true또는로 평가되는 표현식이 무엇인지에 대해 앉아 있기 때문 입니다 false. 삼항 문장은 시각적 노이즈로 빠르게 전환되어 가독성을 감소시켜 유지 보수성에 영향을 미치기 때문에 시각적으로 구분하는 것이 좋습니다.
Tin Man

3

운영자가 플레이어의 ID가 1인지 확인하고 결과에 따라 적의 ID를 설정하는 간단한 예

player_id=1
....
player_id==1? enemy_id=2 : enemy_id=1
# => enemy=2

그리고 나는 매우 유용한 주제에 관한 게시물을 발견했습니다 .


4
왜 안돼 enemy_id = player_id == 1 ? 2 : 1?
Aaron Blenkush

1
@AaronBlenkush 우아한 입력 감사합니다. 나는 아직도 멍청한 수준에, 아마도 이유입니다 :)
devwanderer


0

가장 쉬운 방법:

param_a = 1
param_b = 2

result = param_a === param_b ? 'Same!' : 'Not same!'

이후 param_a 없는 동일한 param_b다음 result의 값이 될 것이다Not same!

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.