이 게임쇼는 참가자들이 짧은 루비 코드 스니펫의 출력을 30초 안에 객관식(A, B, C, D)으로 맞추는 방식으로 진행됩니다. 질문은 점차 난이도가 높아지며, 참가자들은 ‘페어 프로그래밍(친구에게 질문)’과 ‘AI에게 묻기(청중 투표)’ 두 가지 라이프라인을 한 번씩 사용할 수 있습니다. 강연자는 첫 번째 예시 문제로 p 1::a.(2)와 같은 특이한 문법을 제시하며, :: 연산자가 네임스페이스 해결뿐 아니라 인스턴스 메서드 호출에도 사용될 수 있음을 설명합니다.
루비의 특이한 문법과 동작 방식
-
논리 AND 할당 연산자 (
&&=):foo &&= 1과 같이 사용될 때,foo가 falsy(nil 또는 false)가 아닌 경우에만 우측 값(1)이 좌측 변수(foo)에 할당됩니다. 초기foo가nil인 경우 할당이 일어나지 않아nil이 출력됩니다. -
연산자 우선순위와 범위 객체 (
1..5.to_a):p 1..5.to_a는(1..5).to_a와 달리5.to_a를 먼저 호출하려 시도하여NoMethodError를 발생시킵니다. 이는 범위 객체에 대한to_a호출 전에 연산자 우선순위로 인해5에 대한to_a가 먼저 시도되기 때문입니다. -
빈 괄호와
nil컨텍스트 (my_method()):my_method()와 같이 빈 괄호를 사용하여 메서드를 호출할 때, 루비는 이를nil컨텍스트로 처리합니다.if nil은falsy이므로, 해당 메서드 내의 조건문은false로 평가됩니다. -
람다의
===연산자:lambda { |x=1| x + 2 } === 3와 같이 람다에===연산자를 사용하면, 람다를 호출하고 그 결과를 우측 값과 비교합니다. 이는 루비의case문이 내부적으로 동작하는 방식과 유사합니다. -
인스턴스 변수 문자열 보간 (
#@hello):p "Hello #@hello"와 같이 인스턴스 변수(@hello), 클래스 변수(@@var), 전역 변수($var)는 중괄호 없이#만으로 문자열 내에서 보간될 수 있습니다. -
메서드 호출 시 중괄호의 블록 처리 (
stringify({})):stringify {}와 같이 괄호 없이 중괄호를 전달하면, 루비는 이를 블록으로 해석하여 메서드 인수가 누락되었다는ArgumentError를 발생시킵니다. -
단일 문자열 표기법 (
?A + ?1):?A는 루비 1.9 이전 버전에서는 ASCII 코드 포인트(97)를 반환했지만, 이후 버전에서는 단일 문자열 “A”를 반환합니다. 따라서 최신 루비에서는"A" + "1"이 되어"A1"이 됩니다. -
for루프의 스코프 (for num in 1..3 do; end; p num):for루프는 자체 스코프를 생성하지 않고 외부 스코프의 지역 변수나 메서드 이름을 덮어쓸 수 있습니다.def num; 5; end가 정의된 상태에서for num in 1..3을 실행하면, 루프가 끝난 후num은 마지막 값인3이 됩니다. -
정수 문자열 삽입 (
str << 97): 빈 문자열str에 정수97을<<연산자로 삽입하면, 루비는97을 ASCII 코드 포인트로 해석하여 문자 ‘a’로 변환합니다. -
해시 키로서의 연산 결과 및 무한 메서드 (
{ 2 + 2 => def foo; end }): 해시 키는2 + 2와 같은 연산 결과(4)가 될 수 있으며, 값으로는 무한 메서드(def foo; end)와 같은 표현식이 사용될 수 있습니다. -
Proc의 호출 방식 및 유연성 (Proc.new { hello } []):Proc는.없이 대괄호([])로 직접 호출될 수 있으며, 람다와 달리 인수의 개수에 덜 엄격합니다. 또한proc는 예약어가 아닙니다. -
sleep메서드의 반환 값 (sleep 1.5):sleep메서드는 실제로 잠든 시간을 반올림하여 반환합니다. 특정 상황에서는 예측 가능한1,2의 값을 번갈아 반환하는 결정론적 동작을 보이기도 합니다.
이러한 예시들은 루비의 유연성과 예측 불가능한 측면을 보여주지만, 동시에 가독성 높은 코드를 작성하는 것의 중요성을 강조합니다.