루비로 시작하는 프로그래밍

일반인을 위해 프로그래밍을 가르쳐주는 튜토리얼.

8장. 메서드 만들기

Writing Your Own Methods

나만의 메서드를 만들어 봅시다.

앞에서 살펴보았듯이, loop와 iterator들을 사용하면 같은 코드를 실행하는 등 같은 일을 계속해서 반복할 수 있습니다. 하지만 가끔 같은 것을 프로그램의 다른 곳에서 여러차례 실행하기를 원합니다.

예를 들어 심리학 학생을 위한 설문 프로그램을 작성한다고 해봅시다. 내가 알고있는 심리학 학생들과 학생들이 내게 준 설문지들로 아마 다음과 같은 일을 할겁니다.

puts '안녕하세요, 시간을 내주셔서 감사합니다. '
puts '제 실험을 도와주세요. 제 실험은'
puts '사람들이 멕시코 음식에 대해 느끼는 방식에 대한 것과 관련이 있습니다.'
puts '멕시코 음식에 대해서 한번 생각해 보세요'
puts '그리고 다음의 질문에 솔직하게 답해주세요,'
puts 예나 아니오로 답해주세요. 제 실험은'
puts '밤에 이불에 오줌을 싸는 것과는 상관이 없습니다.'
puts

#  우리는 다음의 질문들을 던지지만, 사용자가 입력하는 답은 무시할 겁니다.

goodAnswer = false
while (not goodAnswer)
  puts '타코를 좋아하시나요??'
  answer = gets.chomp.downcase
  if (answer == '예' or answer == '아니오')
    goodAnswer = true
  else
    puts '예나 아니오로 답해주세요.'
  end
end

goodAnswer = false
while (not goodAnswer)
  puts '부리또를 좋아하시나요??'
  answer = gets.chomp.downcase
  if (answer == '예' or answer == '아니오')
    goodAnswer = true
  else
    puts '제발요, 예나 아니오로 답해주세요.'
  end
end

#  *this* 이 답에는 주의를 기울일 거예요.

goodAnswer = false
while (not goodAnswer)
  puts '밤에 이불에 오줌을 싸시나요??'
  answer = gets.chomp.downcase
  if (answer == 예' or answer == '아니오')
    goodAnswer = true
    if answer == '예'
      wetsBed = true
    else
      wetsBed = false
    end
  else
    puts '예 또는 아니오로 답하세요.'
  end
end

goodAnswer = false
while (not goodAnswer)
  puts '치미찬가스를 좋아하시나요??'
  answer = gets.chomp.downcase
  if (answer == '예' or answer == '아니오')
    goodAnswer = true
  else
    puts '예나 아니오로 답해주세요.'
  end
end

puts '몇 가지만 더 질문드릴게요...'

goodAnswer = false
while (not goodAnswer)
  puts '소파필라스 좋아하세요??'
  answer = gets.chomp.downcase
  if (answer == '예' or answer == '아니오')
    goodAnswer = true
  else
    puts 'Please answer "예" or "아니오".'
  end
end

# 멕시코 음식에 대해서 다른 질문을 많이 던지세요.

puts
puts 'DEBRIEFING:'
puts 'Thank you for taking the time to help with'
puts 'this experiment.  In fact, this experiment'
puts 'has nothing to do with Mexican food.  It is'
puts 'an experiment about bed-wetting.  The Mexican'
puts 'food was just there to catch you off guard'
puts 'in the hopes that you would answer more'
puts 'honestly.  Thanks again.'
puts
puts wetsBed
Hello, and thank you for taking the time to
help me with this experiment.  My experiment
has to do with the way people feel about
Mexican food.  Just think about Mexican food
and try to answer every question honestly,
with either a "yes" or a "no".  My experiment
has nothing to do with bed-wetting.

Do you like eating tacos?
yes
Do you like eating burritos?
yes
Do you wet the bed?
no way!
Please answer "yes" or "no".
Do you wet the bed?
NO
Do you like eating chimichangas?
yes
Just a few more questions...
Do you like eating sopapillas?
yes

DEBRIEFING:
Thank you for taking the time to help with
this experiment.  In fact, this experiment
has nothing to do with Mexican food.  It is
an experiment about bed-wetting.  The Mexican
food was just there to catch you off guard
in the hopes that you would answer more
honestly.  Thanks again.

false

꽤 긴 프로그램이었죠, 반복되는 부분도 많았고요. (맥시코 음식에 관한 질문에 해당하는 코드 부분은 모두 동일하고 이불에 오줌싸는지에 관한 질문은 약간씩만 달라요.) 프로그램에서 동일한 것을 반복해서 쓰는 것은 안 좋은 겁니다. 반복한다고 하면 loop나 iterator를 쓰고 싶을 수가 있는데 여기서는 쓸 수가 없습니다. 왜냐하면 질문을 던지는 중간중간에 하고 싶은 게 있기 때문이에요. 이런 경우에는 메서드를 작성하는 것이 최고죠. 어떻게 하면 되는지 다음을 봅시다.

def sayMoo
  puts '음메...'
end

어.. 우리의 프로그램이 '음메' 하지 않았네요. 왜 안했을까요? 왜냐하면 얘기하라고 하지 않았기 때문입니다.

어떻게 음메~ 하라고만 얘기했지 실제로 말하라고는 하지 않았습니다. 다른걸 보죠.
(역자주: 아마도 여기에 오리가 꽥꽥거리는 삽화가 있겠네요:))

def sayMoo
  puts '음메...'
end

sayMoo
sayMoo
puts '꽥꽥'
sayMoo
sayMoo

#실행결과

음메..
음메..
꽥꽥
음메...
음메...

아.. 훨씬 더 낫네요.(프랑스어를 모르는 경우를 대비해서 설명하자면, 프로그램 안에 프랑스 오리가 있었고 프랑스어로 오리는 "꽥꽥(coin-coin)이라고 말합니다.)

그래서 위에서 method sayMoo를 정의했습니다. (변수이름 같은 Method 이름들은 소문자들로 시작합니다. +, ==과 같이 몇가지 예외가 있지만요)

하지만 method들이 항상 object들과 연관되어야 하지 않나요? 예 그렇죠, 이 경우(puts과 gets들을 가짐), method는 전체 프로그램을 대표하는 오브젝트와 연관되어 있습니다.

다음 장에서는 다른 오브젝트에 메서드를 추가하는 방법에 대해서 살펴볼겁니다. 하지만 먼저 살펴보로 게 있습니다...

메서드에 인자 넘겨주기

gets나 to_s, reverse 같은 몇몇 메쏘드는 객체에다 바로 호출할 수 있다는 것을 알아차렸을 거예요. 하지만 +나 -,  puts같은 다른 메서드들을 호출하려면, 인자를 알려줘야 합니다. 예를 들어, '5+2'가 아니라, '5+' 라고만 말한다면 컴퓨터가 이해할 수 없잖아요? 5에게 뭔가를 더하라고 말하면서도, 얼마를 더할지는 알려주지 않는 셈이죠.

sayMoo에 인자를 넘겨주려면요 (예를 들면 몇 번 음메를 할 지요), 이렇게 하면 돼요:

def sayMoo numberOfMoos
  puts '음메...'*numberOfMoos
end

sayMoo 3
puts '꿀-꿀'
sayMoo  
# 이 부분은 에러가 날 거예요, 왜냐하면 인자가 없기 때문이죠.

# 실행결과 

음메..음메..음메...
꿀-꿀
#<안자 에러 : 인자 숫자가 틀렸습니다. (0 for 1)>

numberOfMoos는 변수이고요, 이 변수는 메서드에 넘겨주는 매개변수를 가리켜요. 한번 더 말씀드릴게요. 약간 헷갈릴 수도 있거든요. numberOfMoos는 변수이고요, 이 numberOfMoos변수는 메서드에 넘겨주는 인자를 가리켜요. 그래서, sayMoo 3이라고 치면, 매개변수는 3이 되는 거에요. 그리고 numberOfMoos라는 변수는 3을 가리키는 거고요.

이 경우에는 인자가 필요하다는 것을 이해하시겠죠? 한 번 생각해 볼까요? sayMoo에게 '음메...'를 여러번 말하라고 하면서, 몇 번 말하라고 말해주지 않는다면 대체 컴퓨터는 어떻게 해야 할까요? 불쌍한 컴퓨터는 몇 번 '음메~' 해야 할지 직접 생각할 수 없거든요.

루비에 나오는 객체(object)가 영어의 명사와 같다면, 메쏘드는 동사와도 같아요. 그렇다면, 인자는 뭐가 될까요? 부사쯤이 돼요. 이를테면 sayMoo의 경우에, 인자를 사용하면 sayMoo를 '어떻게' 수행해야 하는지를 알려주는 거죠. 또 어떤 때에는 인자는 직접 목적어가 되기도 해요. puts의 메서드에서, 인자를 넘겨주면, 그 인자를 출력하잖아요? 이 경우에는 직접 목적어가 되는 거죠.

지역 변수가 뭔지 알아볼까요?

다음에 나오는 프로그램에는 두 개의 변수가 나옵니다:

def doubleThis num
  numTimes2 = num*2
  puts num.to_s+' doubled is '+numTimes2.to_s
end

#실행결과

doubleThis 44

44 doubled is 88

이 두 개의 변수는 각각 num과 numTimes2라는 이름을 가집니다. 두 개의 변수 둘다 doubleThis라는 메소드 안에 있습니다. 여러분이 이제까지 본 변수는 모두 지역 변수에요. 이 얘기는 지역 변수는 메소드 안에서만 산다는 의미예요. 그리고 메소드 밖으로 나갈 수 없죠. 메소드 밖으로 나가려고 하면 에러가 납니다.

def doubleThis num
  numTimes2 = num*2
  puts num.to_s+' doubled is '+numTimes2.to_s
end

doubleThis 44
puts numTimes2.to_s

#실행결과

44 doubled is 88
#<NameError: undefined local variable or method `numTimes2' for #
<StringIO:0x82ba21c>>

정의되지 않은 지역 변수... 사실 우리는 지역 변수를 정의해줬어요. 우리가 사용하려던 그 지역의 지역 변수로 정의해주지 않았던 거지요. 그래서 그 변수는 메소드에게는 지역적이지 않았던 거예요. 이런 점은 불편하게 여겨질 수도 있지만, 사실 이것은 좋은 방식이예요. 이렇게 하면 메소드 안의 변수에 접근할 수 없게 되죠. 이 얘기는 다른 사람들이 여러분의 변수에 접근할 수 없다는 의미가 되고요, 즉 여러분의 변수를 바꾸어서 엉망으로 만들어놓을 수 없다는 의미가 됩니다.  

def littlePest var
  var = nil
  puts 'HAHA!  I ruined your variable!'
end

var = 'You can\'t even touch my variable!'
littlePest var
puts var

#실행결과

HAHA!  I ruined your variable!
You can't even touch my variable!

이름의 이 작은 프로그램에는 var라는 이름의 변수가 두 개있습니다. 변수 한 개는 littlePest 안쪽에 있고요, 다른 하나는 littlePest의 바깥 쪽에 있습니다. littlePest var를 호출했을 때, 실제로 우리는 하나의 var에서 다른 var로 문자열을 넘겨주었습니다. 결국 두 개는 모두 같은 문자열을 가리키게 되죠. 그리고 나서  littlePest는 자신의 지역 var변수가 nil을 가리키도록 합니다. 그러나 메소드 바깥 쪽에 있는 var에는 아무런 변화도 주지 않죠.

메서드가 반환하는 값

몇몇 메소드는 호출했을 때 여러분에게 무언가를 돌려준다는 것을 알아차리셨을 거예요. 예를 들어 gets 메소드는 여러분이 타이핑한 문자열을 반환하고요, 5+3에서 + 메소드는 (사실은 5. +(3) 라고 호출한 셈이죠.)8을 반환합니다. 수를 가지고 산수계산을 하는 메소드는 수를 반환하고요, 문자열을 가지고 연산하는 메소드는 문자열을 반환합니다.

호출했을 때 어떤 값을 반환하는 메소드와 화면에다가 어떤 정보를 보여주는 프로그램(예를 들어 puts메소드를 쓰면 화면에다가 정보를 보여주죠) 간에는 차이가 있습니다. 이 차이를 아는 것이 중요해요. 예를 들어볼까요? 5+3라고 호출하면 8을 반환하지만 8을 화면에다 보여주지는 않습니다.

그럼 puts 메소드가 반환하는 것은 무엇일까요? 전에는 이 부분에 대해서 신경쓰지 않았지만, 이번에는 한 번 살펴보지요.

returnVal = puts 'This puts returned:'     // ‘이번에 호출한 puts가 반환한 것입니다.’
puts returnVal

#실행결과

This puts returned:
nil

즉 첫번째 호출한 puts메소드는 nil이라는 값을 반환했습니다. 테스트를 해보지는 않았지만, 두번째 호출한  puts메소드도 역시 nil을 반환했을 거예요. puts는 항상 nil을 반환합니다. 모든 메소드는 무언가를 반환해야 합니다. 반환값이 nil이라고 하더라도 말이죠.

잠깐 쉬어 갈까요? 쉬는 동안 프로그램을 하나 만듭니다. 이 프로그램은 sayMoo가 반환한 값이 무엇인지 알아내는 프로그램이에요.

놀랐나요? 흠. 이 프로그램이 작동하는 방식을 알려 드릴게요. 이 메소드가 반환하는 값은 메소드의 가장 마지막 줄입니다. sayMoo 메소드의 경우에는 puts ‘음메.......’ * numberOfMoos가 되겠죠. 그리고 이 값은 nil입니다. 왜냐하면 puts는 항상 nil을 반환하기 때문이죠. 만약 어떤 메소드가 ‘노란 잠수함'이라는 문자열을 반환하게 하고 싶으면 그냥 그 문장을 메소드의 가장 마지막 줄에 쓰면 되요:

def sayMoo numberOfMoos
  puts '음메...'*numberOfMoos
  '노란 잠수함'
end

x = sayMoo 2
puts x

#실행결과

음메... 음메...
노란 잠수함

자, 이제 다시 심리테스트를 해봅시다. 이 메서드에서는요, 질문을 인자로 넘겨받아야 합니다, 그리고 대답이 ‘예'이면 true를, ‘아니오'이면 no를 반환해야죠. (대부분의 경우 그 대답을 실제로는 무시하더라도, 메서드에서는 반환을 하게 하는 것이 좋습니다. 이런 메서드를 만들어두면 이불에 오줌을 싸느냐는 질문을 할 때에도 쓸 수가 있죠.) 이제 앞에 인사말 부분과 debriefing 부분을 짧게 줄일게요, 더 읽기 편하도록이요:

(Todo : 본문에 있는 ' ' 안에 있는 것 - 한국어로 바꾸기)

def ask question
  goodAnswer = false
  while (not goodAnswer)
    puts question
    reply = gets.chomp.downcase
    
    if (reply == 'yes' or reply == 'no')
      goodAnswer = true
      if reply == 'yes'
        answer = true
      else
        answer = false
      end
    else
      puts 'Please answer "yes" or "no".'
    end
  end
 
  answer  #  This is what we return (true or false).
end

puts 'Hello, and thank you for...'
puts

ask 'Do you like eating tacos?'      #  We ignore this return value.
ask 'Do you like eating burritos?'
wetsBed = ask 'Do you wet the bed?'  #  We save this return value.
ask 'Do you like eating chimichangas?'
ask 'Do you like eating sopapillas?'
ask 'Do you like eating tamales?'
puts 'Just a few more questions...'
ask 'Do you like drinking horchata?'
ask 'Do you like eating flautas?'

puts
puts 'DEBRIEFING:'
puts 'Thank you for...'
puts
puts wetsBed

#실행결과

Hello, and thank you for...

Do you like eating tacos?
yes
Do you like eating burritos?
yes
Do you wet the bed?
no way!
Please answer "yes" or "no".
Do you wet the bed?
NO
Do you like eating chimichangas?
yes
Do you like eating sopapillas?
yes
Do you like eating tamales?
yes
Just a few more questions...
Do you like drinking horchata?
yes
Do you like eating flautas?
yes

DEBRIEFING:
Thank you for...

false

괜찮죠? 그쵸? 더 많은 질문을 추가할 수도 있게 만들었습니다. 그리고 이제는 질문을 추가하는 게 쉬워졌죠. 우리가 만든 프로그램이 좀 더 짧아졌어요. 아주 잘 한 거예요. 프로그램을 이렇게 더 짧게 만드는 것이 프로그래머의 꿈이거든요!

또 하나의 큼직한 예제를 살펴 봅시다.

이 쯤에서 또 한 가지 예제를 만들어보면 좋을 것 같네요. 이 프로그램은 englishNumber라고 부를 거예요. 이 프로그램은 예를 들면 22같은 수를 받아들여서, 이 수의 영어 버전, 즉 이 경우에는 ‘twenty-two’라는 문자를 반환합니다. 자, 우선은 0에서 100 사이에 있는 정수에 대해서 작동하는 프로그램을 만들어 봅시다.

(주의하세요: 이 메소드는 return이라는 키워드를 사용해서, 메소드로부터 반환하는 새로운 트릭을 사용할 거예요. 그리고 elsif라는 새로운 분기점 만드는 법을 소개할 거예요. 아래 예제를 따라가다보면 어떤 식으로 작동하는 지 이해하실 거예요.)

def englishNumber number
  #  We only want numbers from 0-100.
  if number < 0
    return 'Please enter a number zero or greater.'
  end
  if number > 100
    return 'Please enter a number 100 or lesser.'
  end
 
  numString = ''  #  This is the string we will return.
 
  #  "left" is how much of the number we still have left to write out.
  #  "write" is the part we are writing out right now.
  #  write and left... get it?  :)
  left  = number
  write = left/100          #  How many hundreds left to write out?
  left  = left - write*100  #  Subtract off those hundreds.
 
  if write > 0
    return 'one hundred'
  end
 
  write = left/10          #  How many tens left to write out?
  left  = left - write*10  #  Subtract off those tens.
 
  if write > 0
    if write == 1  #  Uh-oh...
      #  Since we can't write "tenty-two" instead of "twelve",
      #  we have to make a special exception for these.
      if    left == 0
        numString = numString + 'ten'
      elsif left == 1
        numString = numString + 'eleven'
      elsif left == 2
        numString = numString + 'twelve'
      elsif left == 3
        numString = numString + 'thirteen'
      elsif left == 4
        numString = numString + 'fourteen'
      elsif left == 5
        numString = numString + 'fifteen'
      elsif left == 6
        numString = numString + 'sixteen'
      elsif left == 7
        numString = numString + 'seventeen'
      elsif left == 8
        numString = numString + 'eighteen'
      elsif left == 9
        numString = numString + 'nineteen'
      end
      #  Since we took care of the digit in the ones place already,
      #  we have nothing left to write.
      left = 0
    elsif write == 2
      numString = numString + 'twenty'
    elsif write == 3
      numString = numString + 'thirty'
    elsif write == 4
      numString = numString + 'forty'
    elsif write == 5
      numString = numString + 'fifty'
    elsif write == 6
      numString = numString + 'sixty'
    elsif write == 7
      numString = numString + 'seventy'
    elsif write == 8
      numString = numString + 'eighty'
    elsif write == 9
      numString = numString + 'ninety'
    end
    
    if left > 0
      numString = numString + '-'
    end
  end
 
  write = left  #  How many ones left to write out?
  left  = 0     #  Subtract off those ones.
 
  if write > 0
    if    write == 1
      numString = numString + 'one'
    elsif write == 2
      numString = numString + 'two'
    elsif write == 3
      numString = numString + 'three'
    elsif write == 4
      numString = numString + 'four'
    elsif write == 5
      numString = numString + 'five'
    elsif write == 6
      numString = numString + 'six'
    elsif write == 7
      numString = numString + 'seven'
    elsif write == 8
      numString = numString + 'eight'
    elsif write == 9
      numString = numString + 'nine'
    end
  end
 
  if numString == ''
    #  The only way "numString" could be empty is if
    #  "number" is 0.
    return 'zero'
  end
 
  #  If we got this far, then we had a number somewhere
  #  in between 0 and 100, so we need to return "numString".
  numString
end

puts englishNumber(  0)
puts englishNumber(  9)
puts englishNumber( 10)
puts englishNumber( 11)
puts englishNumber( 17)
puts englishNumber( 32)
puts englishNumber( 88)
puts englishNumber( 99)
puts englishNumber(100)
zero
nine
ten
eleven
seventeen
thirty-two
eighty-eight
ninety-nine
one hundred

이 프로그램에 대해서 몇 가지 마음에 안 드는 점이 있습니다. 우선 반복되는 부분이 너무 많아요. 둘째로, 100보다 큰 수는 다루지를 못해요. 세번째는 예외인 경우가 너무 많아요. 그리고 반환하는 경우도 너무 많고요. 배열을 사용해서 좀 더 깔끔하게 만들어 봅시다.

def englishNumber number
  if number < 0  #  No negative numbers.
    return 'Please enter a number that isn\'t negative.'
  end
  if number == 0
    return 'zero'
  end
 
  #  No more special cases!  No more returns!
 
  numString = ''  #  This is the string we will return.
 
  onesPlace = ['one',     'two',       'three',    'four',     'five',
               'six',     'seven',     'eight',    'nine']
  tensPlace = ['ten',     'twenty',    'thirty',   'forty',    'fifty',
               'sixty',   'seventy',   'eighty',   'ninety']
  teenagers = ['eleven',  'twelve',    'thirteen', 'fourteen', 'fifteen',
               'sixteen', 'seventeen', 'eighteen', 'nineteen']
 
  #  "left" is how much of the number we still have left to write out.
  #  "write" is the part we are writing out right now.
  #  write and left... get it?  :)
  left  = number
  write = left/100          #  How many hundreds left to write out?
  left  = left - write*100  #  Subtract off those hundreds.
 
  if write > 0
    #  Now here's a really sly trick:
    hundreds  = englishNumber write
    numString = numString + hundreds + ' hundred'
    #  That's called "recursion".  So what did I just do?
    #  I told this method to call itself, but with "write" instead of
    #  "number".  Remember that "write" is (at the moment) the number of
    #  hundreds we have to write out.  After we add "hundreds" to "numString",
    #  we add the string ' hundred' after it.  So, for example, if
    #  we originally called englishNumber with 1999 (so "number" = 1999),
    #  then at this point "write" would be 19, and "left" would be 99.
    #  The laziest thing to do at this point is to have englishNumber
    #  write out the 'nineteen' for us, then we write out ' hundred',
    #  and then the rest of englishNumber writes out 'ninety-nine'.
    
    if left > 0
      #  So we don't write 'two hundredfifty-one'...
      numString = numString + ' '
    end
  end
 
  write = left/10          #  How many tens left to write out?
  left  = left - write*10  #  Subtract off those tens.
 
  if write > 0
    if ((write == 1) and (left > 0))
      #  Since we can't write "tenty-two" instead of "twelve",
      #  we have to make a special exception for these.
      numString = numString + teenagers[left-1]
      #  The "-1" is because teenagers[3] is 'fourteen', not 'thirteen'.
      
      #  Since we took care of the digit in the ones place already,
      #  we have nothing left to write.
      left = 0
    else
      numString = numString + tensPlace[write-1]
      #  The "-1" is because tensPlace[3] is 'forty', not 'thirty'.
    end
    
    if left > 0
      #  So we don't write 'sixtyfour'...
      numString = numString + '-'
    end
  end
 
  write = left  #  How many ones left to write out?
#
  left  = 0     #  Subtract off those ones.
#
 
  if write > 0
    numString = numString + onesPlace[write-1]
    #  The "-1" is because onesPlace[3] is 'four', not 'three'.
# “-1”을 넣는 이유는 onesPlace[3]은 ‘3’이 아니라 ‘4’이기 때문이에요.
  end
 
  #  Now we just return "numString"...
  numString
end

puts englishNumber(  0)
puts englishNumber(  9)
puts englishNumber( 10)
puts englishNumber( 11)
puts englishNumber( 17)
puts englishNumber( 32)
puts englishNumber( 88)
puts englishNumber( 99)
puts englishNumber(100)
puts englishNumber(101)
puts englishNumber(234)
puts englishNumber(3211)
puts englishNumber(999999)
puts englishNumber(1000000000000)

#실행결과

zero
nine
ten
eleven
seventeen
thirty-two
eighty-eight
ninety-nine
one hundred
one hundred one
two hundred thirty-four
thirty-two hundred eleven
ninety-nine hundred ninety-nine hundred ninety-nine
one hundred hundred hundred hundred hundred hundred

아아.. 이렇게 하니까 훨씬 더 낫군요. 이 프로그램은 꽤나 빼곡합니다. 그래서 위에서 처럼 주석을 많이 달아두었어요. 이 프로그램은 큰 수에 대해서도 작동합니다. 하지만 기대만큼 잘 작동하지는 않아요. 예를 들어 ‘1백만 1백만'이라는 결과보다는 ‘1조'라는 결과가 더 낫겠죠. 물론 둘 다 맞더라도요. 사실 이것을 할 수 있다면... (흠.. 다음에 나오는 것이랑 연결시키는 부분인가? 이것을 할 수 있다면 뒤에 나오는 것을 함 해보라?;)

프로그램 만들어보기

위에서 만든 englishNumber 프로그램을 확장시키세요.

원래는 100까지만 처리할 수 있었는데요, 1000 단위도 처리할 수 있도록 고쳐주세요. 프로그램이 확장되면, '십백' 대신에 '천'을 반환해야 합니다. 그리고 '백백' 대신에 '백만'을 반환해야 하고요.

englishNumber 프로그램을 좀 더 확장하세요.

자 이제 백만 단위도 처리되게 하세요. 이제는 '천천'이 아니라 '백만'이 반환되어야 합니다.그 다음에는 십억과 1조도 추가해 보세요. 얼마나 높은 단위까지 처리하게 구현할 수 있나요?

결혼기념일을 표시해주는 프로그램(weddingNumber)을 만들어 보세요.

이 프로그램은 englishNumber과 거의 같은 기능을 합니다. 단 다른 점이 있다면, 이 프로그램은 모든 곳에 '그리고'라는 단어를 집어넣어야 한다는 거예요. 예를 들어서 '천구백 그리고 칠십 그리고 이'를 반환해야 합니다. 또는 결혼식 청첩장에서 통상적으로 쓰는 형식대로 문자열을 반환해야 합니다. 몇 가지 예제를 더 드리고는 싶지만, 저도 청첩장에 연도를 어떤 형식으로 보여주는지는 잘 모르겠어요. 이에 대해 자세하게 알려면 결혼식 코디네이터에게 물어보는 편이 빠르겠죠? :)

"맥주 아흔아홉병..."

앞에서 만든 프로그램하고 수를 읽어주는 englinshNumber를 사용해서, 이번에는 노래가사를 제대로 화면에 보여주는 프로그램을 만들어 보세요. 컴퓨터에게 벌을 주세요. 9999부터 시작하게 하세요. 하지만 너무 큰수부터 시작하게 하지는 마세요, 왜냐하면 화면에 너무 큰 수를 보여주려면 컴퓨터가 시간이 좀 많이 걸릴 수도 있으니까요. 수십만 병을 화면에 보여주려면 시간이 꽤 걸릴 거에요; 그리고 백만병을 고른다면, 아마 여러분이 괴로워질 거예요!!

8장을 마무리하며

축하합니다! 자, 이제 여러분은 진정한 프로그래머가 되었습니다! 아주 큰 프로그램을 처음부터 만드는데 필요한 모든 것을 여러분은 모두 배웠어요. 직접 만들어보고 싶은 프로그램이 있다면, 한 번 만들어 보세요! 물론 프로그램을 처음부터 만들면 꽤나 느릿느릿하게 진행될 수도 있어요. 다른 사람이 이미 작성한 적이 있는 코드를 모두 다시 새로 쓸 필요가 있을까요? 이메일을 보내주는 프로그램을 만들고 싶으시다구요? 컴퓨터에서 파일을 불러오고, 파일로 저장하고 싶다고요? 코드 샘플을 자동으로 다 테스트해주는 튜토리얼 페이지를 만들고 싶으시다고요? 루비에는 여러 가지 다양한 객체들이 있답니다. 이것들을 가지고 더 좋은 프로그램을 더 빨리 만들 수가 있죠!
 

참고

댓글

댓글 본문
  1. 에러의화신
    예제코드 수정좀 부탁드릴게요 복사하면서 보다보니 puts 메소드부분에 따옴표를 빼먹은것들이 여러개 보이네요