Ruby in Twenty Minutes 4

이 전에 만들었던 새로운 프로그램을 좀더 자세히 살펴봅시다. # 마크로 시작하는 줄은 Ruby에서 주석을 나타낼때 사용합니다. 이 마크가 사용된 줄은 interpreter가 무시하게 됩니다. The first line of the fileis a special case, and under a Unix-like operating system tells theshell how to run the file.(이부분은 무슨 뜻인지 모르겠네요;;) 나머지 주석들은 프로그램의 명확성을 위해 사용되었습니다.

say_hi 메소드가 좀더 기술적으로 변했습니다.

# Say hi to everybody
def say_hi
if @names.nil?
puts "..."
elsif @names.respond_to?("each")
# @names is a list of some kind, iterate!
@names.each do
|name|
puts "Hello #{name}!"
end
else
puts "Hello #{@names}!"
end
end

@names를 보고 분기를 합니다. 만약에 nil이면 점 세개를 출력합니다.

Cycling and Looping—a.k.a. Iteration

만약에 @names 객체가 each에 반응을 하면 iterator를 사용할 수 있다는 것이고 그것을 사용하여 각각의 사람들에게 인사를 하면 되겠네요.

반복에 대해 좀더 자세히 살펴봅시다.

@names.each do
|name|
puts "Hello #{name}!"
end

each는 코드 블럭을 받아들이는 메소드로써 리스트에 있는 모든 원소들을 상대로 코드 블럭을 실행합니다. do와 end 사이가 블럭에 해당합니다. A block is like an anonymous functionor lambda. 블럭은 파이프들(| |) 사이에 있는 변수가 이 블럭에서 사용될 파라미터입니다.

여기서는 리스트 안에 있는 모든 요소들을 name으로 가리키고 이것을 사용하여  puts “Hello #{name}!” 를 실행했군요.

다른 프로그래밍 언어의 경우 리스트의 요소들을 반복할 때 for loop를 사용합니다.
(C언어 스타일 같은 경우 다음과 같이 표현 합니다.)

for (i=0; i<number_of_elements; i++)
{
do_something_with(element[i]);
}

이것도 작동은 하지만 우아하진 않습니다. 여기서는 i와 같은 변수를 필요로 합니다.
i는 리스트의 길이를 나타내고 리스트에서 어떤 순으로 작업을 할지 알려줍니다.
하지만 Ruby는 좀더 우아한 방법을 사용합니다.
모든 구체적인 것들은 each 메소드 안에 숨겨 놨습니다. 우리가 할일은 오직 리스트안에 있는
각각의 요소들이 each문 안에서 어떠한 작업을 할 것인지만 기술하면 됩니다.

Blocks, the Highly Sparkling Glint on the Edge of Ruby

블럭은 리스트보다 더 복잡한 것들을 다룰 때 사용합니다. 메소드를 가지고 구체적인 것들을 다룰수 있는 것을 물론이고 셋업, 분해, 에러들 또한 다룰 수 있습니다

# Say bye to everybody
def say_bye
if @names.nil?
puts "..."
elsif @names.respond_to?("join")
# Join the list elements with commas
puts "Goodbye #{@names.join(", ")}. Come back soon!"
else
puts "Goodbye #{@names}. Come back soon!"
end
end

say_bye 메소드는 each를 사용하지 않고 대신에 @names가 join 메소드에 반응 하는지를 체크 합니다. 그리고 만약에 반응한다면 join을 사용합니다. 반응하지 않으면 그냥 변수를 문자열로 출력합니다. 이 메소드는 변수의 실제 타입을 신경쓰지 않습니다. 이 메소드가 지향하는 것은 “Duck Typing”입니다. “만약에 오리같은 것이 들어오면 오리처럼 꽥꽥거려라..”. 라는 것이죠. 이런것의 장점은 변수들의 불필요한 타입 제약을 가하지 않는다는 것입니다. 만약에 새로운 타입의 리스트를 가지고 온다면 (join 메소드를 구현한 것이여야 겠죠.) 모든 일들이 계획된 대로 진행될 것입니다.

Kicking Off the Script

여기까지가 MegaGreeter 클래스 였고 남은 부부는 이 클래스의 메소드를 호출하여 사용하는 부분입니다. 이게 Ruby in Twenty Minutes 여기서 배울 마지막 트릭이군요.

if
__FILE__ == $0

_FILE_ 이것은 현재 파일이름을 가지고 있는 마술 같은 변수 입니다. $0 은 프로그램을 시작하기 위해 사용되는 파일의 이름입니다. 이 문장은 “만약에 이 파일이 실행되는 파일이면…” 이라는 뜻입니다. 어떤 파일이 그냥 library 로 사용될 것이라면 저 문장에 걸렸을 때 실행되지 안을 것이고 만약에 파일이 실행될 수 있는 파일이면 다음 코드가 실행될 것입니다.

Consider Yourself Introduced

여기까지가 Ruby의 quick tour 였습니다. 하지만 아직 살펴 볼 것들이 많습니다.(제어문, 블럭, 모듈들,,)
Documentation 이곳에 가시면 여러 문서들이 무료로 제공됩니다.
만약에 책을 보고 싶으신 분들은 book list이곳을 클릭하여 살펴보시면 됩니다.

Ruby in Twenty Minutes 3

저번 글에서 만들어 두었던 class의 객체를 생성합시다.


g 객체를 한번 생성하면 그 이름이 Pat이라는 것을 기억하는군요. 흠.. 만약에 name 변수에 직접 접근하면 어떻게 될까요?


오호.. 안되는 군요..

Under the Object’s Skin

인스턴스 변수들은 항상 객체 속안에 숨겨져 있습니다. (인스턴스 변수는 @name 과 같이 @를 붙여서 만드나 봅니다.) 심하게 감춰져 있지는 않고 객체를 조사해보면 그들에게 접근 할 수 있는 다른 방법들이 존재합니다만…Ruby는 data를 숨기기 좋은 객체 지향 접근법을 사용합니다.

그럼 Greeter 객체 안에는 어떤 메소드들이 있을까요?


와오.. 엄청나게 많네요. 여기 보이는 메소드들은 Greeter 객체가 가지고 있는 모든 메소드입니다. 조상(부모도 포함됐겠죠? :)으로 부터 받은 많은 메소드들도 포함되어 있습니다. 만약에 우리가 만든 method들만 보고 싶다면 조상들에게 정의되어 있는 메소드를 보길 원치 않는 다는 의미로 false를 파라미터로 넘겨주면 됩니다.


자 그럼 이제 어떤 method들이 우리가 가진 객체가 반응을 하는지 봅시다:


say_hi와 to_s(어떤 것을 string으로 바꿔주는 method군요. 기본적으로 모든 객체들이 가지고 있습니다.) 그러나 name이란 메소드는 모르네요.

Altering Classes—It’s Never Too Late

만약에 name을 바꾸거나 보고 싶다면 어떻게 해야할까요? Ruby는 객체의 변수에 접근할 수 있는 쉬운 방법을 제공합니다.


Ruby에서는 class를 다시 열어서 수정을 할 수 있습니다. 기존에 이미 만들어져 있는 객체들은 바뀌지 않지만 이 후에 새로 만들어지는 객체들은 영향을 받습니다. 그래서 이제 새로운 객체를 만들고 @name 속성을 가지고 놀아봅시다.


attr_accessor 을 사용해서 getter에 해당하는 name과 setter에 해당하는 name= 두개의 메소드를 정의했습니다.

Greeting Anything and Everything, MegaGreeter Neglects None!

이 greeter 는 그다지 흥미롭지 않군요. 이 class는 오직 한번에 한사람만 다루는데요 여러 사람들에게 인사를 하는 class를 만들 순 없을까요?

그렇게 할 수 것을 Ruby interpreter인 IRB에 직접 쓰는 대신에 파일로 만들어 봅시다.

IRB를 끝내기 위해서 “quir”이나 “exit” 또는 그냥 컨트롤+D 를 입력합니다.

C:\Documents and Settings\keesun>ruby
class MegaGreeter
attr_accessor :names

#Create the object
def initialize(names = “world”)
@names = names
end

#Say hi to everybody
def say_hi
if @names.nil?
puts “…”
elsif @name.respond_to?(“each”)

@name.each do
|name|
       puts “Hello #{name}!”
     end
   else
   puts “Hello #{@names}!”
   end
  end

  # Say bye to everybody
  def say_bye
   if @names.nil?
     puts “…”
   elsif @names.respond_to?(“join”)
     # Join the list elements with commas
     puts “Goodbye #{@names.join(“, “)}.  Come back soon
   else
     puts “Goodbye #{@names}.  Come back soon!”
   end
  end

end

if __FILE__ == $0
  mg = MegaGreeter.new
  mg.say_hi
  mg.say_bye

  # Change name to be “Zeke”
  mg.names = “Zeke”
  mg.say_hi
  mg.say_bye

  # Change the name to an array of names
  mg.names = [“Albert”, “Brenda”, “Charles”,
   “Dave”, “Englebert”]
  mg.say_hi
  mg.say_bye

  # Change to nil
  mg.names = nil
  mg.say_hi
  mg.say_bye
end

cmd창을 열고 위처럼 입력한 뒤

컨트롤 + c를 입력하면 위에 입력한 것을 바로 처리합니다.

Hello world!
Goodbye world.  Come back soon!
Hello Zeke!
Goodbye Zeke.  Come back soon!
Hello AlbertBrendaCharlesDaveEnglebert!
Goodbye Albert, Brenda, Charles, Dave, Englebert.  Come back soon!

위와 같은 결과를 보셨다면 제대로 된 것입니다.

윈도우의 도스창에서 바로 실행시키지 않고.

위의 코드를 ri20min.rb 라고 저장한 뒤 ruby ri20min.rb 를 이용하여 실행하여도 같은 결과를 볼 수 있습니다.

Ruby in Twenty Minutes 2

저번에 이어 이번에는 “Hello World!”를 매번 전부 타자를 치지 않고 출력하는 방법은 없을 까요?

메소드를 만들어 봅시다.


위와 같이 코딩을 합니다.

def h 는 method 정의 부분을 시작하는 코드입니다. 이것은 Ruby에게 우리가 h라는 이름의 method를 정의하고 있다는 것을 알려줍니다.
다음 줄은 method의 body에 해당합니다. 우리가 전에 봤던 명령줄이랑 같습니다.
마지막으로 end는 Ruby에게 method 정의가 끝났다는 것을 알려줍니다.
Ruby의 nil 응답은 우리에게 method가 정의 됐다는 것을 알려줍니다.

The Brief, Repetitive Lives of a Method

이제는 위에서 만든 method를 몇번 호출해 봅시다.

매우 쉽네요. Ruby에서 method를 호출하는 방법은 method 이름을 부르면 되네요. 만약에 parameter들을 필요로 하지 않는 method라면 이렇게 해도 되는게 맞습니다. 비어있는 괄호를 추가시켜서 부를 수도 있지만 꼭 그럴 필요는 없지요.

만약에 kee sun이 아닌 특정 사람에게 인사를 전하고 싶다면 어떻게 해야할까요? h method가 이름을 parameter로 가지도록 재정의 하면 되겠네요.


몇가지 트릭이 사용되었는데요. 먼저 parameter로 이름을 주면서 method를 호출 해보고 다음에는 paramter가 없는 method를 다시 호출해 보았습니다. default parameter로 kee sun을 주었습니다. 이것은 name으로 오는 parameter가 없으면 “kee sun”을 출력하라는 것이네요.
그리고 원문에는 설명이 나와있지 않지만 아무래도 문자열.capitalize 메소드를 호출하면 문자열의 첫 문자를 대문자로 바꿔주는 듯 하네요.

Evolving Into a Greeter

만약에 진짜 greeter를 원한다면 어떨까요. 당신의 이름을 기억해두었다가 항상 당신에게 존경을 표하는 그런 것 말입니다. 당신은 아마도 그것을 위해 객체를 사용하길 원할 것입니다. “Greeter” class를 만들어 봅시다.


여기 새로 추가된 keyword는 class입니다. 이것은 Greeter라고 이름으로 새로운 class 정의 하고 class안에 method들을 정의합니다. @name 은 class내의 다른 method들에서 접근이 가능한 instance 변수 입니다. say_hi 와 say_bye 에서 사용한 것을 확인할 수 있습니다.

오늘은 여기까지 입니다. 다음 번에는 객체를 생성하여 사용하는 것을 살펴보겠습니다.

원문 : http://www.ruby-lang.org/en/documentation/quickstart/2/

번역 + 편역 : 기선