select
select
select 표현식은 블로킹 연산들 중에서 선택해서, 가장 먼저 사용 가능해지는 분기로 진행해요. 여러 채널이나 타임아웃을 동시에 기다라다가 먼저 완료되는 것을 처리하는 데 유용해요.
출처: Crystal 공식 문서
본문
문법 (Syntax)
표현식은 select 키워드로 시작하고, 하나 이상의 when 분기 목록이 뒤따라요. 각 분기는 조건과 본문을 가지며, 둘은 문장 구분자 또는 then 키워드로 구분돼요. 선택적으로 마지막 분기는 else(조건 없이)일 수 있는데, 이는 select 동작을 비블로킹으로 만드는 것을 뜻해요. 표현식은 end 키워드로 끝나요.
참고:
select는 모든 분기가 잠재적으로 블로킹되는 연산을 가리키는case표현식과 비슷해요.
각 조건은 select 동작(select action)에 대한 호출이거나, 오른쪽이 select 동작 호출인 할당이에요.
select
when foo = foo_channel.receive
puts foo
when bar = bar_channel.receive?
puts bar
when baz_channel.send
exit
when timeout(5.seconds)
puts "Timeout"
end
Select 동작들 (Select actions)
select 동작 호출은 암시적 접미사 _select_action가 붙은 메서드를 호출해요. ? 접미사가 붙은 호출이라면 _select_action?를 호출하죠. 이 메서드는 select 동작의 인스턴스를 반환해요.
select 표현식은 각 분기에 연결된 select 동작을 시작해요. 둘 중 하나가 즉시 반환하면 그것으로 진행해요. 그렇지 않으면 완료를 기다려요. 하나의 분기가 완료되는 즉시 다른 모든 분기는 취소돼요. else 분기는 즉시 완료되므로 기다리는 일이 없어요.
실행은 완료된 분기에서 계속돼요. 분기 조건이 할당이라면, select 호출의 결과가 대상 변수에 할당돼요.
표준 라이브러리는 다음과 같은 select 동작들을 제공해요:
Channel#send_select_actionChannel#receive_select_actionChannel#receive_select_action?::timeout_select_action
더 알아보기
select는 여러 블로킹 연산 중 먼저 완료되는 분기로 진행해요.- 각 분기는
_select_action메서드로 연결되고,else분기를 두면 비블로킹이 돼요. - 채널
send/receive와timeout을 함께 써서 타임아웃을 구현할 수 있어요.