루비 튜토리얼
이 글은 프로그래밍에 대해 어느정도는 알고 있는 사람을 대상으로 빠르게 루비(프로그래밍 언어)를 정복하기 위한 글입니다.
출력
puts "Hello, World!" # Hello, World!
puts 'Hello, World!' # Hello, World!
출력은 puts 명령어를 사용합니다. 큰 따음표("")와 작은 따음표("")는 같은 의미를 가지는 것 같지만 사실 조금 다릅니다. 만약 newline(\n)이나 tab(\t) 등을 사용하고 싶다면 큰 따음표를 사용해야 합니다. 작은 따음표는 그저 그대로 출력하게 되죠.
puts "Hello,\tWorld" # Hello, World
puts 'Hello,\tWorld' # Hello,\tWorld
입력
gets
gets 명령어로 사용자로부터 입력을 받을 수 있습니다. 물론 위 코드처럼 gets 만 쓰면 입력을 받기만 할 뿐 아무 동작도 하지 않습니다. 그래서 종종 다음과 같이 사용합니다.
puts gets # 입력한 내용을 그대로 출력함
var1 = gets # 입력한 내용을 var1 에 넣음
루비에서 gets 는 입력을 받을때 newline(\n)도 입력을 받습니다. 만약 Hello 를 입력하고 var1 에 넣으면 var1 의 길이는 5가 아닌 6이 된다는 의미입니다. 왜냐하면 Hello\n 이기 때문이죠. 이를 방지하기 위해서는 chomp 를 사용해야 합니다.
# 입력이 Hello 라 합시다
var1 = gets # Hello\n (길이: 6)
var2 = gets.chomp # Hello (길이: 5)
산술 연산자
1 + 2 # 3
3 - 2 # 1
4 * 3 # 12
5 / 2 # 2
정수들 간 나눗셈은 정수 나눗셈을 따릅니다. 사칙연산 외에도 유용한 연산자들이 존재합니다. ** 는 제곱 연산자이며 % 는 나머지 연산자입니다.
5 ** 2 # 25
5 % 2 # 1
문자열
문자열은 큰 따음표("") 또는 작은 따음표('')를 통해 표현하는 값입니다. 덧셈 및 곱셈이 가능합니다.
'Hello' + 'World' # HelloWorld
'Hello' + ', ' + 'World' # Hello, World
'Hello' * 3 # HelloHelloHello
자료형 변환
정수, 실수, 문자열은 서로 형태를 변환할 수 있습니다. 정수형으로 변환은 to_i, 실수형으로 변환은 to_f, 문자열로 변환은 to_s 를 사용하면 됩니다.
'123' # 123
'123' + '123' # 123123
'123'.to_i + '123'.to_i # 246
123 + 123 # 246
123.to_s + 123.to_s # 123123
5 / 2 # 2
5 / 2.0 # 2.5
5 / 2.to_f # 2.5
변수와 상수
name = 'woojin'
age = 24
puts name # woojin
puts age # 24
루비는 데이터 타입에 대해 미리 선언할 필요가 없습니다. 변수는 값을 바꿀 수 있으며 상수는 바꿀 수 없습니다. 루비에서 변수를 생성할 때 첫 글자를 대문자로 하면 상수가 됩니다. 신기하죠
Name = 'woojin' # 상수
Name = 'woojin2' # 에러, 상수는 변할 수 없음.
난수
srand 0 # 시드
rand() # 0.0 ~ 1.0 (모든 실수)
rand(100) # 0 ~ 100 (정수)
srand 0 은 시드값이 없는 무작위 값을 만들어냅니다. 만약 시드 값을 사용하고 싶다면 srand 뒤에 0 이 아닌 값을 넣어주면 됩니다.
조건문과 반복문
if num1 == 50
puts "50 입니다."
elsif num < 50
puts "50 보다 작아요."
else
puts "50 보다 커요."
end
분기의 마지막마다 end 가 들어가는 것과 elif 도, else if 도 아닌 elsif 가 사용된다는 점에 유의하시기 바랍니다. 반복문도 크게 다르지는 않습니다.
while number > 0
puts number
number /= 2
end
배열
a = Array.new # 빈 배열 생성 1
b = [] # 빈 배열 생성 2
numbers = [1, 2, 3, 4]
numbers # 1 2 3 4
numbers[0] # 1
numbers[1,3] # 2, 3, 4 (인덱스 1부터 3개의 값)
배열에 접근할 때는 at 을 사용할 수도 있습니다. 단 at 키워드는 배열의 범위를 초과하는 값에 접근해도 에러를 발생시키지 않습니다. 에러를 위해서는 fetch 를 사용하면 되며 이는 의외로 유용합니다.
numbers = [1, 2, 3, 4]
numbers.at(5) # 값이 없기 때문에 아무것도 출력하지 않는다.
numbers.fetch(5) # 값이 없기 때문에 에러
배열에 값을 추가하기 위해서는 push 나 << 를 사용하면 됩니다.
numbers.push(5) # numbers 배열에 5 추가
numbers.push(3, 6) # numbers 배열의 3번 인덱스에 6 추가
numbers << 7 # numbers 배열에 7 추가
do
루비에서 배열의 원소들을 출력하거나 할 때 do 를 사용합니다. 코드로 보여드리면 다음과 같습니다.
numbers.each do |number|
puts number
end
# numbers 배열의 모든 원소를 출력합니다.
루비에서 모든 타입은 객체이기 때문에 다음과 같은 짓(?)도 가능합니다.
3.times do |index|
puts index
end
# 0, 1, 2
Proc
Proc 은 프로시져의 줄임말로 객체이자 익명함수입니다. 자바스크립트의 콜백 함수와 비슷합니다.
sayHello = Proc.new do
puts 'Hello, World!'
end
sayHello # Hello, World!
이 코드는 hello 를 출력하는 간단한 프로시저 하나를 생성하는 코드입니다. 만약 Proc 에서 매개변수를 사용하려면 다음과 같이 하면 됩니다.
sayHello = Proc.new do |name|
puts 'Hello, ' + name
end
sayHello woojin # Hello, woojin
이후에 나올 함수를 사용해도 hello 를 출력하는 것을 만드는 것은 가능합니다. 그러면 왜 Proc 을 사용할까요? 함수와 달리 Proc 는 매개변수로 넘겨줄 수 있기 때문입니다.
def printProc myProc
myProc.call
end
printProc sayHello # Hello, World!
메서드
메서드는 함수라고도 하며, 같은 코드를 여러번 써야할 필요가 존재할 때 유용한 방법입니다.
def hello
puts "Hello, World!"
end
hello # Hello, World!
다음과 같이 매개변수를 넣어줄 수도 있습니다.
def hello name
puts "내 이름은 " + name
end
hello # 내 이름은 ~~~
메서드에는 꽤나 유용한 것들이 많이 있습니다. 다음과 같이 말이죠. (이 외에도 더 많은 것들이 있습니다.)
word = 'aBc'
puts word.reverse # cBa
puts word.length # 3
puts word.upcase # ABC
puts word.downcase # abc
puts word.swapcase # AbC
puts word.capitalize # ABc (가장 앞글자만 대문자로)
puts word.center(5) # aBc
puts word.ljust(5) # aBc
puts word.rjust(5) # aBc
words = ['b', 'c', 'a']
puts words.join(', ') # b, c, a
puts words.sort # a b c
클래스
클래스는 객체를 만들기 위해 사용하는 구조나 틀을 말합니다.
class Hello
def initialize
@var1 = 'Hello'
var2 = 'World'
end
def sayHello
puts @var1
end
def sayWorld
puts var2
end
end
a = Hello.new
puts a.sayHello # Hello
puts a.sayWorld # 에러
initialize 는 클래스의 인스턴스를 처음 생성할 때 시행하는 메서드입니다. 파이썬에서 __init__ 과 C++ 에서 constructor 를 말합니다. 클래스는 반드시 상수로 선언해야 하며 안에 여러 메서드를 사용할 수 있습니다. 상수 타입은 위에서 어떻게 선언하는지 말했었죠?
이때 변수의 종류가 여러개인 것을 확인할 수 있습니다. @ 를 사용하는 @var1 은 인스턴스 변수입니다. 이 변수는 인스턴스가 가지고 있는 값을 말합니다. 만약 @ 를 사용하지 않으면 var2 처럼 지역 변수가 됩니다. 이 값은 initialize 메서드 내에서는 사용할 수 있지만 그 밖에서는 사용할 수 없습니다. 그래서 sayWorld 에서 var2 가 할당되지 않아 에러가 발생하죠.
루비에서 모든 데이터 타입은 클래스로 선언되어 있기 때문에 이런 짓도 가능합니다.
class Integer
def printTenTimes
puts self.to_s * 10
end
end
puts 3.printTenTimes # 3333333333
그 외에...
위에서 말한 것 이외에도 루비는 정말 많은 특징을 가지고 있습니다. 다 다룰수는 없지만 간단한 몇몇 가지를 아래에서 다루도록 하겠습니다.
# Time
c = Time.new
puts c # 2020-07-01 00:16:33 +0900 (지금시간)
puts c + 60 # 2020-07-01 00:17:33 +0900 (1분후)
# Time 생성하기
puts Time.mktime(1997, 5, 12, 0, 0) # 1997-05-12 00:00:00 +0900
# Hash
color = Hash.new
color["strings"] = "red"
color["numbers"] = "blue"
puts color # {"strings"=>"red", "numbers"=>"blue"}
puts color.key("red") # strings
puts color["numbers"] # blue
# Math
puts Math::PI # 3.141592653589793
puts Math::E # 2.718281828459045
puts Math.log(Math::E**2) # 2.0
puts Math.sqrt(5) # 2.23606797749979