본문 바로가기
old/Web Application 개발 이야기

2. 루비(Ruby) 언어 정리(조건문, 순환문, 메소드 그리고 블럭)

by 열야 2010. 1. 28.

if문
if 조건 [then |:]
#코드
elsif 조건 [then|:]
#코드
else 조건 [then|:]
#코드
end
특이한 것은 조건에 ()괄호가 없다는 것
뒤에 then또는 :을 쓸 수 있는데 안써도 된다는 것
각 블록마다 블록의 끝을 나타내는 end가 있는 것이 아니라 if문의 끝에만 end를 붙여야 한다는 것이다.

unless
if 내의 조건에 not이 붙은 것과 동일하지만, elsif를 사용할 수 없다.
unless 조건 [then |:]
#코드
else
#코드
end

if와 unless를 수식어 형태로 사용하기 (perl에도 있는 방식)
한줄짜리 조건식에 사용하기 좋으나, 가독성이 떨어질 수 있는 단점이 있다.
temperture = 76
puts "Picnic time!" unless temperature < 65 || temperature > 85
이경우, unless의 조건이 false이므로 puts "Picnic time!"이 실행된다.

case~when문
다른 언어의 switch와 비슷하다. 바로 예를 들면..
command = "Stop"

case command
when "Go"
    puts "Going"
when "wait"
    puts "waiting"
when "Turn"
    puts "Turning"
when "Stop"
    puts "Stopping"
else
    puts "I can't understand that"
end

특이한 것은 break를 쓰지 않아도 다음 when절이 나타나기 전에 끝난 다는 것이랑 default대신 else라는 점이다.
아마 언어 제작자는 이를 switch보다는 if문의 파생으로 생각한 듯 싶다.

case문을 다음과 같이 사용할수도 있다. 음.. 무슨 철학인지..ㅡ.ㅡ?
temperature = 76

message = case
when (0...65) === temperature
    "Too cold"
when (85...120) === temperature
   "Too hot"
when (65...85) === temperature
   "Picnic time!"
else
   "Temperature out of reasonable range!"
end

puts message

순환문 while
while($_ != "q")
    puts "Running..."
    print "Enter q to quit: "
    gets
    chomps
end

until문
while문의 조건이 not인 경우이다.

while과 until의 수식어 형태 용법
if와 unless와 동일하게 수식어 형태로 사용할 수 있다. 반복문을 이렇게 사용하는 경우는 매우 드물 듯...
value = 0
value += 1 while value < 100

for문
for문은 다른 언어의 for라기보다는 foreach와 비슷하다.
for 변수 in [배열 | 해쉬 | 범위]
#코드
end

Ruby의 반복자 사용법
반복자로서는 upto, downto, step, times가 있다. 이 반복자는 변수나 상수의 메소드들인 것 같다.
upto는 현재 자신부터 지정된 숫자까지 반복
downto는 자신부터 지정된 숫자까지 하향 반복
step은 자신부터 지정된 숫자까지, 두번째 지정된 숫자만큼씩 증가하여 반복
times는 자신만큼 반복
이것만 읽으면 외계어 같군.. 예를 보자.
grades = [88, 99, 73, 56, 87, 64]
sum = 0
0.upto(grades.length - 1) do |loop_index|
    sum += grades[loop_index]
end
-----------
puts "What's the answer?"
sum = 0
4.step(12, 2) do |even_value|
    sum += even_value
end

순환문 내의 break, redo, next
break: 그냥 멈춤 (C의 break와 동일)
redo: 블록의 시작으로 가서 변화 없이 다시 시작
next: 실행을 바로 종료하고 다음 루프로 진행 (C의 continue와 동일)
-10.upto(10) do |number|
    next if number == 0
    puts "1/" + number.to_s + " = " + (1 / Float(number)).to_s
end

순환문 내의 retry 문
루프를 그냥 처음부터 다시 시작

메소드를 정의하고 실행하는 방법
1. 인자가 없는 경우
def 함수명
    #코드
end

2. 인자가 있는 경우
def 함수명 (message, name)
    #코드
end

3. 인자가 있으나 그 수를 모르는 경우
def 함수명 (first_argu, *others)
    #코드
end
*others에서 *은 배열을 나타낸다.

함수의 값 반환(return)
return을 사용한다.
여러개를 return할 수 있다.

def incrementer(value)
    return value + 1
end

def greeting()
    return "No", "worries"
end

블록
루비에서의 블록을 정의하는 방법은 두가지이다.
{}는 한줄로 된 블록을 정의할 때 사용하고
do와 end는 여러줄로 된 블록을 지정할 때 사용된다.
재미 있는 점은 블록이 무슨 함수처럼 인자를 받을 수 있다는 점이다!!
다른 언어에서는 블록은 프로그램의 실행되고 변수가 제한되는 코드 블럭이지만, 루비에서는 코드 블럭 역할도 하지만, 함수에 넘겨줄 수도 있고 인자도 받고 그런다.. 신기하다. @.@

def greeting ()
    yield
end

greeting { puts "Hello there!" }

메소드에 전달된 블럭을 실행하는 방법은 yield문을 사용하면 된다. 위와 같이 하면 Hello there!가 출력된다.
만약 greeting을 다음과 같이 정의하면
def greeting ()
    yeild
    yeild
    yeild
    yeild
end
와 같이 정의한 후 위와 같이 블럭을 넘기면 Hello there!가 4번찍힌다.

블록에서 데이터 전달받기 (인자 받기)
def greeting ()
    yield "Hello", "there"
end

greeting {|word_one, word_two| puts word_one + " " + word_two }
이와 같이 하면, word_one에 "Hello"가 word_two에 "there"가 삽입되게 된다.

BEGIN, END블럭
루비의 기능인 것 같다. 이 블럭을 정의하면 BEGIN블럭은 스크립트가 메모리에 로딩될 때 자동으로 실행되고, END는 종료될 대 자동으로 실행된다.
BEGIN {puts "Hi "}

puts "there "

END {puts "sweetie."}