265 lines
5.3 KiB
Markdown
265 lines
5.3 KiB
Markdown
# **Ruby 메서드와 블록**
|
|
|
|
Ruby는 간결하고 유연한 문법을 제공하는 언어로, 메서드와 블록을 활용하면 가독성이 뛰어나고 재사용 가능한 코드를 작성할 수 있다. 이번 글에서는 **메서드**와 **블록**을 중심으로 설명하겠다.
|
|
|
|
---
|
|
|
|
## **1. Ruby 메서드(Method)**
|
|
|
|
Ruby에서 메서드는 특정 동작을 수행하는 코드의 묶음이다. 다른 프로그래밍 언어에서 함수(function)와 비슷하지만, Ruby에서는 모든 것이 객체이므로 메서드 역시 객체에 속한다.
|
|
|
|
### **1.1. 메서드 정의와 호출**
|
|
|
|
메서드는 `def` 키워드를 사용하여 정의하며, `end`로 닫는다.
|
|
|
|
```ruby
|
|
def say_hello
|
|
puts "Hello, Ruby!"
|
|
end
|
|
|
|
say_hello # 메서드 호출
|
|
```
|
|
|
|
#### **매개변수가 있는 메서드**
|
|
|
|
```ruby
|
|
def greet(name)
|
|
puts "안녕하세요, #{name}님!"
|
|
end
|
|
|
|
greet("Alice") # "안녕하세요, Alice님!"
|
|
```
|
|
|
|
#### **기본값을 갖는 매개변수**
|
|
|
|
```ruby
|
|
def greet(name = "Ruby")
|
|
puts "안녕하세요, #{name}님!"
|
|
end
|
|
|
|
greet # "안녕하세요, Ruby님!"
|
|
greet("Alice") # "안녕하세요, Alice님!"
|
|
```
|
|
|
|
#### **여러 개의 인수 받기 (가변 인수, splat 연산자 `*`)**
|
|
|
|
```ruby
|
|
def sum(*numbers)
|
|
numbers.sum
|
|
end
|
|
|
|
puts sum(1, 2, 3, 4, 5) # 15
|
|
puts sum(10, 20, 30) # 60
|
|
```
|
|
|
|
`*numbers`는 가변 길이의 인수를 배열로 변환하여 처리한다.
|
|
|
|
---
|
|
|
|
### **1.2. 반환값(Return Value)**
|
|
|
|
Ruby의 메서드는 기본적으로 마지막 실행된 표현식의 결과를 반환한다.
|
|
|
|
```ruby
|
|
def add(a, b)
|
|
a + b # 마지막 줄이 반환값
|
|
end
|
|
|
|
puts add(3, 7) # 10
|
|
```
|
|
|
|
`return` 키워드를 사용하면 명시적으로 값을 반환할 수 있다.
|
|
|
|
```ruby
|
|
def add(a, b)
|
|
return a + b
|
|
end
|
|
```
|
|
|
|
하지만, Ruby에서는 `return`을 생략하는 것이 일반적이다.
|
|
|
|
---
|
|
|
|
### **1.3. 키워드 인수(Keyword Arguments)**
|
|
|
|
Ruby 2.0부터 키워드 인수를 지원하여 가독성이 높아졌다.
|
|
|
|
```ruby
|
|
def introduce(name:, age:)
|
|
puts "이름: #{name}, 나이: #{age}"
|
|
end
|
|
|
|
introduce(name: "Alice", age: 25)
|
|
```
|
|
|
|
기본값을 설정할 수도 있다.
|
|
|
|
```ruby
|
|
def introduce(name: "홍길동", age: 20)
|
|
puts "이름: #{name}, 나이: #{age}"
|
|
end
|
|
|
|
introduce # "이름: 홍길동, 나이: 20"
|
|
introduce(name: "Bob") # "이름: Bob, 나이: 20"
|
|
```
|
|
|
|
---
|
|
|
|
## **2. 블록(Block)과 반복문**
|
|
|
|
블록은 `{}` 또는 `do...end`로 감싸는 코드 덩어리다. 특정 메서드에서 실행할 코드를 블록으로 전달할 수 있다.
|
|
|
|
```ruby
|
|
3.times { puts "Ruby!" }
|
|
```
|
|
|
|
```ruby
|
|
3.times do
|
|
puts "Ruby!"
|
|
end
|
|
```
|
|
|
|
위 두 코드는 동일한 결과를 출력한다.
|
|
|
|
---
|
|
|
|
### **2.1. 블록을 사용하는 메서드**
|
|
|
|
블록을 전달받는 대표적인 메서드로 `each`가 있다.
|
|
|
|
```ruby
|
|
[1, 2, 3].each { |num| puts num }
|
|
```
|
|
|
|
```ruby
|
|
[1, 2, 3].each do |num|
|
|
puts num
|
|
end
|
|
```
|
|
|
|
---
|
|
|
|
### **2.2. 블록을 명시적으로 호출 (`yield`)**
|
|
|
|
Ruby에서는 `yield`를 사용하여 블록을 실행할 수 있다.
|
|
|
|
```ruby
|
|
def with_greeting
|
|
puts "안녕하세요!"
|
|
yield # 블록 실행
|
|
puts "좋은 하루 되세요!"
|
|
end
|
|
|
|
with_greeting { puts "블록 내부 실행!" }
|
|
```
|
|
|
|
출력 결과:
|
|
```
|
|
안녕하세요!
|
|
블록 내부 실행!
|
|
좋은 하루 되세요!
|
|
```
|
|
|
|
#### **블록에 값 전달**
|
|
|
|
```ruby
|
|
def twice
|
|
yield 1
|
|
yield 2
|
|
end
|
|
|
|
twice { |num| puts "숫자: #{num}" }
|
|
```
|
|
|
|
출력 결과:
|
|
```
|
|
숫자: 1
|
|
숫자: 2
|
|
```
|
|
|
|
---
|
|
|
|
### **2.3. 블록을 매개변수로 받기 (`&block`)**
|
|
|
|
블록을 명시적으로 매개변수로 받으려면 `&block`을 사용한다.
|
|
|
|
```ruby
|
|
def repeat(n, &block)
|
|
n.times { block.call }
|
|
end
|
|
|
|
repeat(3) { puts "블록 실행!" }
|
|
```
|
|
|
|
출력 결과:
|
|
```
|
|
블록 실행!
|
|
블록 실행!
|
|
블록 실행!
|
|
```
|
|
|
|
블록이 주어지지 않은 경우의 예외 처리는 `block_given?`을 사용한다.
|
|
|
|
```ruby
|
|
def optional_block
|
|
if block_given?
|
|
yield
|
|
else
|
|
puts "블록이 없습니다!"
|
|
end
|
|
end
|
|
|
|
optional_block # "블록이 없습니다!"
|
|
optional_block { puts "블록이 실행됨!" }
|
|
```
|
|
|
|
---
|
|
|
|
### **2.4. `Proc`과 `Lambda`**
|
|
|
|
Ruby에서는 블록을 `Proc` 또는 `Lambda` 객체로 저장할 수도 있다.
|
|
|
|
#### **Proc 객체**
|
|
|
|
```ruby
|
|
say_hello = Proc.new { puts "Hello!" }
|
|
say_hello.call # "Hello!"
|
|
```
|
|
|
|
#### **Lambda 객체**
|
|
|
|
```ruby
|
|
greet = ->(name) { puts "안녕하세요, #{name}님!" }
|
|
greet.call("Alice")
|
|
```
|
|
|
|
`Proc`과 `Lambda`의 차이점은 `return` 동작 방식과 매개변수 처리 방식에 있다.
|
|
|
|
```ruby
|
|
def test_proc
|
|
p = Proc.new { return "Proc 리턴" }
|
|
p.call
|
|
"메서드 종료"
|
|
end
|
|
|
|
puts test_proc # "Proc 리턴" (Proc의 return이 메서드까지 종료)
|
|
|
|
def test_lambda
|
|
l = -> { return "Lambda 리턴" }
|
|
l.call
|
|
"메서드 종료"
|
|
end
|
|
|
|
puts test_lambda # "메서드 종료" (Lambda의 return은 람다 내부만 종료)
|
|
```
|
|
|
|
---
|
|
|
|
## **3. 마무리**
|
|
|
|
Ruby에서 메서드와 블록을 활용하면 가독성과 재사용성이 높은 코드를 작성할 수 있다.
|
|
- **메서드**는 `def`로 정의하며, 매개변수를 가질 수 있다.
|
|
- **블록**은 `{}` 또는 `do...end`로 감싸며, `yield` 또는 `&block`을 사용해 실행할 수 있다.
|
|
- **Proc과 Lambda**를 사용하면 블록을 객체로 다룰 수 있다.
|
|
|
|
이제 Ruby의 메서드와 블록을 활용하여 더 유연한 프로그램을 만들어보자! |