# **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의 메서드와 블록을 활용하여 더 유연한 프로그램을 만들어보자!