Ruby

메소드 (함수)

본 토픽은 현재 준비중입니다.공동공부에 참여하시면 완성 되었을 때 알려드립니다.

메소드

메소드(method)란 다른 언어에서는 함수라고 불리는 것으로 코드의 재사용성을 높여준다. 사실 메소드 이전에 우리가 배웠던 것들로도 프로그램을 만들 수 있다. 그런 점에서 메소드 이전의 내용들은 프로그래밍의 실체라고 할 수 있다. 그 이후부터 등장하는 메소드나 객체지향과 같은 개념들은 그것 자체가 프로그래밍의 연산이나 논리에 직접적으로 관여하는 것이라기 보다는 방대한 양의 코드를 줄여주고, 유지보수를 쉽게하고, 버그가 발생할 여지를 줄여주는 것들이라고 할 수 있다. 이것들 없이 거대한 소프트웨어를 만든다는 것이 불가능하지는 않지만, 현실적으로 어렵다.

메소드의 형식

메소드의 형식은 아래와 같다.

def 메소드이름 [( [인자 [= 기본값]]...[, * 인자 [, &expr ]])]
   코드
end

메소드의 정의와 호출

메소드는 def 뒤에 메소드의 이름이 오고, 다음 행부터 end 이전 행까지 메소드의 내용이 온다. 다음은 메소드의 예를 보여준다. 이 메소드의 이름은 numbering이고 내용은 0부터 9까지를 화면에 출력한다.

def numbering
    i = 0
    while i < 10
		puts i
		i += 1
	end
end

아래 예제는 위의 함수를 호출한다.

numbering()

메소드의 이름 numbering()만 호출하면 언제든지 메소드 numbering을 실행할 수 있다.

루비에서는 메소드를 호출 할 때 괄호()를 사용하지 않아도 된다. 아래는 numbering()과 동일한 동작을 하게 된다.

numbering

메소드가 없다면

아래 예제를 보자. 이전 시간에 0부터 9까지 출력하는 애플리케이션을 만들었다. 그런데 0부터 9까지를 5번 출력해야 한다면 어떻게 해야할까? 아래와 같이 해야 할 것이다.

i = 0
while i < 10
    puts i
	i += 1
end

i = 0
while i < 10
    puts i
	i += 1
end

i = 0
while i < 10
    puts i
	i += 1
end

i = 0
while i < 10
    puts i
	i += 1
end

i = 0
while i < 10
    puts i
	i += 1
end

만약 이것을 1000번 해야 한다면? 각각의 로직이 1000 줄에 육박한다면? 그리고 그 내용을 수정해야 한다면? 암담한 느낌이 드는가? 메소드를 사용한다면 이러한 문제를 현저히 줄일 수 있다. 아래의 예제를 보자. 결과는 같지만 로직은 단 한번만 등장한다.

def numbering
    i = 0
	while i < 10
		puts i
		i += 1
	end
end
numbering
numbering
numbering
numbering
numbering

입력과 출력

메소드의 핵심은 입력과 출력이다. 입력된 값을 연산해서 출력하는 것이 메소드의 기본적인 역할이다. 다음은 메소드에서 입력과 출력의 역할을 하는 구문들에 대한 설명이다.

return

메소드 내에서 사용한 return은 return 뒤에 따라오는 값을 메소드의 결과로 반환한다. 동시에 메소드를 종료시킨다. 아래 내용을 보자. 결과는 egoing과 k8805다.

def get_member1
    return 'egoing'
end
puts get_member1

def get_member2
	return 'k8805'
end
puts get_member2

get_member1와 get_member2를 출력(puts)한 결과가 각각 egoing과 k8805인 이유는 메소드 내에서 return을 하기 때문이다.

return은 결과를 반환하는 것 외에 메소드를 중지시키는 역할도 한다. 다음 코드를 보자. 결과는 egoing이다.

def get_member
    return 'egoing'
	return 'k8805'
	return 'sorialgi'
end
puts get_member

k8805와 sorialgi는 출력하지 않았다. 왜 그럴까? 그것은 return 'egoing'을 실행한 후에 메소드가 종료되었기 때문이다. return 'k8805' 이하는 어떠한 경우도 실행되지 않는다.

루비에서는 return이 없는 경우 루비에서는 마지막 구문을 리턴 값으로 간주한다. 다음 예를 보자. 결과는 300이다. 마지막 구문이 암시적으로 return k = 300으로 실행된 것이다.

def get_no_return()
   i = 100
   j = 200
   k = 300
end
puts get_no_return

또 다른 특징은 여러개의 리턴값을 줄 수 있다는 점이다. 다음 예제를 보자.

def get_no_return()
   i = 100
   j = 200
   k = 300
   return i, j, k
end
puts get_no_return

결과는 아래와 같다.

100
200
300

위의 결과는 배열을 리턴한 것이다. 배열은 뒤에서 배우기 때문에 여기선 언급하지 않겠다.

인자

인자의 이해

인자(argument)는 메소드로 유입되는 입력 값을 의미하는데, 어떤 값을 인자로 전달하느냐에 따라서 메소드가 반환하는 값이나 메소드의 동작방법을 다르게 할 수 있다. 다음 예를보자. 결과는 1,2이다.

def get_argument(arg)
    return arg
end

puts get_argument 1
puts get_argument 2

5행의 get_argument은 1행에서 3행 사이에 정의된 메소드를 실행하는 구문이다. 5행의 1은 get_argument로 1이라는 값을 전달하겠다는 의미다. 이 때 1행에 정의된 (arg) 구문에 의해서 변수 arg의 값으로 숫자 1이 메소드 안으로 전달된다. 이 변수는 get_argument 안에서만 유효하다. 이 관계는 아래의 그림과 같다.

복수의 인자

그럼 여러개의 입력 값을 받고 싶다면 어떻게 해야할까? 다음 예제를 보자. 결과는 30과 50이다.

def get_arguments(arg1, arg2)
    return arg1 + arg2
end
puts get_arguments 10, 20
puts get_arguments 20, 30

위의 예제를 그림으로 나타내면 아래와 같다. 즉 메소드를 호출할 때 전달한 인자 10과 20은 메소드 선언부(1행)의 arg1, arg2에 차례대로 할당된다. 이렇게 전달된 값은 메소드 내부로 전달되서 더해진 후에 반환된다.

앞서 설명했던 것처럼 루비에서는 메소드를 호출 할 때 괄호를 생략할 수 있다. 위의 예제는 괄호를 생략한 사례다. 아래의 코드는 위와 동일하게 동작한다.

puts get_arguments(10, 20)
puts get_arguments(20, 30)

인자의 기본값

만약 메소드를 호출 할 때 기본값을 사용하고 싶다면 어떻게 해야할까? 기본값이란 인자의 값이 주어지지 않았을 때 사용할 값을 의미한다. 다음 예제를 보자. 결과는 1, 100이다.

def get_arg_default(arg = 100)
    return arg
end
puts get_arg_default 1
puts get_arg_default 

1행의 arg = 100 은 인자 arg의 기본 값으로 100을 사용하겠다는 의미다. 그렇게되면 인자의 값이 설정되지 않았을 때 arg의 값은 100이 된다.

참고

  • 봤어요 0명

댓글

댓글 본문
  1. egoing
    위의 내용에 반영했습니다. 혹시 잘못된 것이 없는지 검토해주시겠어요? ^^
    대화보기
    • egoing
      아 루비에서는 return 값이 없어도 값을 반환 할 수 있다는 점을 말씀하시는거군요!
      대화보기
      • egoing
        첫번째 예제에서는 return이 등장하지 않는데 그 것외에 제가 모르는 루비의 다른 기능이 있는 걸까요? 아니면 return이 없는 함수도 있을 수 있다는 것은 명확하게 공지하는 것이 좋겠다는 의견이신가요? 후자라면 그렇게 하도록 하겠습니다 :)
        대화보기
        • Tw Shim
          루비에서 return은 생략가능하다는것도 설명해주시는게 좋을 것 같아요.