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

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

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

4장. 함께 사용하기

수와 문자열을 함께 사용하기

수와 문자열을 함께 사용하기

지금까지 함께 다른 종류의 객체(숫자와 문자열)에 대해 살펴보았습니다. 그리고 객체를 가리키는 변수도 만들어 봤고요. 이번에는 이 두가지를 섞어서 함께 사용해 보겠습니다. 25를 출력하고 싶다면 다음의 코드는 숫자와 문자열을 더하는 것이기 때문에 동작하지 않는다는 것은 확인했죠.

var1 = 2
var2 = '5'

puts var1 + var2

또 다른 문제가 있어요. 여러분이 (2 + 5)의 결과인 7을 원하는지, 또는 (‘2’ + ‘5’)의 결과인 25를 원하는지 컴퓨터가 알 수 없다는 것입니다. 이 둘을 더하기 전에, 우리는 var1의 문자열 버전을 얻는 방법, 그리고 var2의 정수 버전을 얻는 방법이 필요합니다.

숫자를 문자로, 문자를 숫자로 바꾸기

객체의 문자열 버전을 얻기위해서는 객체 다음에 .to_s를 적으면 됩니다.

var1 = 2
var2 = '5'

puts var1.to_s + var2

#실행결과

>> 25

비슷하게, to_i는 객체의 정수 버전을 돌려주고, to_f는 실수 버전을 돌려줍니다. 이 세 메서드가 어떻게 동작하는지(그리고 어떻게 동작하지 않는지) 좀 더 자세히 보시죠.

var1 = 2
var2 = '5'

puts var1.to_s + var2
puts var1 + var2.to_i

#실행결과

>> 25
>> 7

주의해야 할 점은, to_s 를 호출해서 var1의 문자열 버전을 받은 후에도, var1은 여전히 2(숫자)를 가리키지 절대로 ‘2’ (문자열)를 가리키지 않는다는 것입니다. 명시적으로 var1에 다시 할당(= 기호가 필요)하지 않는 한, 프로그램이 종료될 때까지 2를 가리킵니다.

자 이제 좀 더 재미있고, 조금 더 어려운 변환을 살펴볼까요.

puts '15'.to_f
puts '99.999'.to_f
puts '99.999'.to_i
puts ''
puts '내가 가장 좋아하는 수는 5다!'.to_i
puts 'Who asked you about 5 or whatever?'.to_i
puts 'Your momma did.'.to_f
puts ''
puts 'stringy'.to_s
puts 3.to_i

#실행결과

>> 15.0
>> 99.999
>> 99
>>
>> 5
>> 0
>> 0.0
>>
>> stringy
>> 3

아마, 결과가 조금 놀라울 겁니다. 첫 줄은 정상적으로 15.0이 되었습니다. 다음으로, 문자열 ‘99.999’를 실수와 정수로 변환하였습니다. 실수는 예상했던 대로 변환되었고, 정수 역시 여느 때처럼 내림 되어 변환되었습니다.

그 다음은 조금 별난 문자열을 숫자로 변환하려는 예제들입니다. to_i 는 문자열의 첫 번째가 숫자가 아니면, 문자열의 남은 부분과 상관없이 무시해버립니다. 그래서 첫 번째 별난 문자열은 5로 변환이 되었지만, 나머지 문자열들은 숫자가 아닌 문자로 시작하기 때문에 완전히 무시되어서 컴퓨터가 0을 반환하게 되었습니다.

그리고 마지막 2 변환은 아무 문제 없이 예상대로 변환되었습니다.

puts에 대해 다시 살펴봅시다.

우리가 즐겨 쓰던 메서드에 뭔가 이상한 점이 있습니다. 아래를 한 번 살펴보죠.

puts 20
puts 20.to_s
puts '20'

#실행결과

>> 20
>> 20
>> 20

왜 세가지 경우 모두 같은 것이 출력 될까요? 두 번째 줄의 20.to_s 는 ‘20’ 이니까 밑에 두 줄은 같다고 하더라고, 첫 줄의 정수 20은 어떤가요? 질문을 바꿔보면, 정수 20을 쓴다는 것은 무엇을 의미할까요?

우리가 종이에 2를 쓰고 다음에 0을 쓰는 것은 문자열을 쓰는 것이지 정수를 쓰는 것이 아닙니다. 정수 20은 손가락과 발가락의 수이지, 2다음에 오는 0이 아니라는 것이지요. 바로 여기에 우리의 친구인 puts의 큰 비밀이 숨겨 져있습니다. puts은 객체를 출력하기 전, 객체의 문자열 버전을 가져오기 위해 to_s를 사용합니다. puts에 있는 s는 문자열을 의미하는 것이고 puts의 실제 의미는 ‘문자열(String)을 놓다(put)’ 입니다.

지금 당장은 그렇게 흥미롭게 보이지는 않을 것입니다. 하지만, 루비에 있는 엄청나게 많은 종류의 객체(게다가, 여러분은 객체를 만드는 방법까지 배우게 됩니다!)와 있으며, 할머니의 사진이나, 음악 파일 같은 묘한 객체를 puts를 사용하여 출력하려고 할 때, 어떤 일이 일어나는지 알고 있다면 큰 도움이 될 것입니다.
그동안, 몇 가지 메서드를 더 알려드리겠습니다. 이 메서드들은 재미있는 온갖 종류의 프로그램을 만들 수 있도록 도와줄 것입니다.

gets와 chomp 메서드는 어떤 일을 해줄까요?


puts가 put string의 줄임말이라면, gets가 무엇의 줄임말인지도 추측할 수 있겠죠? 그리고 puts의 결과물이 문자열이듯이 gets의 결과물도 문자열입니다. 그렇다면 gets의 결과물은 어디에서 나오는 것일까요? 바로 우리들입니다. 좀 더 정확히 말하자면, 우리가 입력하는 키보드를 통해서입니다. 키보드는 문자열을 생산해 내기 때문에 gets의 결과물로 쓰기에는 안성맞춤이죠.

gets 메서드가 하는 일이 뭐냐고요? 우리가 엔터키를 누르기 전까지 키보드로 입력한 내용을 그대로 읽어 주는 거예요. 직접 테스트해볼까요?

puts gets

#실행결과

(입력받음) 여기 메아리가 있나?
(출력함) 여기 메아리가 있나?

무엇을 입력하든지 동일한 내용이 화면에 나옵니다. 프로그램을 몇 번 실행 해보고 나서 다른 내용도 입력해 보세요. 이제 소위 인터렉티브한, 즉 상호작용하는 프로그램을 만들 수 있게 되었습니다! 감격스럽죠? 이번에는 이름을 입력하면 인사하는 프로그램을 만들어 봅시다.

puts '안녕, 넌 이름이 뭐니?'
name = gets
puts '네 이름이' + name + '라고? 정말 좋은 이름이구나!'
puts '만나서 만갑다,' + name + '야(아). :)'

#흐억! 방금 이 프로그램을 실행하고, 제 이름을 입력했더니 이런 일이 벌어졌네요.

#실행결과

안녕, 넌 이름이 뭐니? 명수

네 이름이 명수 라고
? 정말 좋은 이름이구나!
만나서 반갑다, 명수야(아)
. :)

흠... 제가 박,명,수 라고 입력하고 엔터키를 눌렀을 때 gets 메서드가 모든 글자와 엔터 키를 인식해버린 것 같네요. 다행히도 이 문제를 해결할 수 있는 메서드가 있습니다. chomp라는 메서드죠.

chomp는 문자열의 맨 뒤에 붙어 있는 엔터 키를 무시하도록 만듭니다. 그럼 이번에는 chomp 메서드의 도움을 받아서 프로그램을 다시 짜 볼까요.

puts '안녕, 넌 이름이 뭐니?'
name = gets.chomp
puts '네 이름이' + name + '라고? 정말 좋은 이름이구나!'
puts '만나서 만갑다,' + name + '야(아). :)'

#실행결과

안녕, 넌 이름이 뭐니? 명수
네 이름이 명수 라고? 정말 좋은 이름이구나!
만나서 반갑다, 명수야(아). :)

한결 낫네요! 우리가 입력한 이름은 gets.chomp를 대체하고 있기 때문에(요부분이 뭔말?), 이름을 입력한 다음에 .chomp를 뒤에 붙이지 않아도 된답니다. 이 점을 눈여겨 보세요. 우리가 입력한 이름에는 이미 chomp 메서드가 적용되어 있습니다. (원문 대조 내용 확인하기!)

프로그램 만들어보기

통성명하는 프로그램

상대방의 성을 묻고, 그 다음 이름을 묻는 프로그램을 짜 봅시다. 마지막에는 상대방의 성명을 부르면서 인사를 건네게 만들어 보세요.

행운의 숫자를 묻는 프로그램

어떤 숫자가 행운의 숫자라고 믿는지 묻는 프로그램을 짜 보세요. 숫자를 입력하면 거기에 1을 더한 숫자를 출력하면서 그 숫자가 더 크고 좋은 숫자라고 대답하는 거죠. (적당히 알아서 재치 있게..)

4장을 마무리하며

위의 두 프로그램과 직접 만들고 싶다고 생각한 프로그램들을 다 완성하셨나요? 이번에는 다른 메서드에 대해서, 그리고 메서드 자체에 대해서 알아 봅시다.

참고

댓글

댓글 본문
  1. jeonghoon
    영어 이름을 입력 하니까 정상 동작하는데, 한글 이름을 입력하니 아래와 같은 메세지가 나오네요.

    carc.rb:3:in `<main>': incompatible character encodings: UTF-8 and CP949 (Encodi
    ng::CompatibilityError)
  2. Luich
    하이라이트 하신 이 부분 뭔말?은 name을 이름으로 번역 하시면서 생긴 오류(?)입니다.
    원 의미는 name이란 '변수'가 gets.chomp를 대체한다.
    즉 gets.chomp에 의해 입력된 문자열인 '박명수'를 대체함으로 뒤에 name변수를 사용 할 때에 .chomp를 붙이지 않아도 된다는 의미입니다.
  3. 행인
    번역 감사합니다~.. 위에 번역중에 '5는 내가 가장 좋아하는 수다.' 라고 바꿔 주시면 더욱 정확한 번역이 될것 같습니다~.. :)
  4. CashCash
    오류)
    안녕, 넌 이름이 뭐니? 명수

    네 이름이 명수
    라고? 정말 좋은 이름이구나!
    만나서 반갑다, 명수
    야(아). :)

    이게 맞는거 같네요
  5. 아마도 원글을 번역하다 발생한 실수 인듯 합니다.
    원문에는 '5 is ...'이어서 그게 맞는거 같습니다.
    대화보기
    • 내일은
      '내가 가장 좋아하는 수는 5다!'.to_i 의 결과 값이 오타 인것 같습니다. 5가 아니고 0이 맞는것 같아요 : )
    버전 관리
    김나솔
    현재 버전
    선택 버전
    graphittie 자세히 보기