함수를 호출할 때, 두 가지의 방식이 있다.
Call by Value(값에 의한 호출)
Call by Reference(참조에 의한 호출)
C에서는 포인터 때문에 좀 더 중요하게 다뤄지는 것 같다.
Ruby에서는 어떤 차이가 있을까?
내 경우, 눈으로 현상을 먼저 확인하는게 이해가 빨랐다.
Ruby irb에서 실행한 결과다.
# 변수의 값이 숫자일 때
irb(main):002:0> a = 0
=> 0
irb(main):003:0> def add(int)
irb(main):004:1> int = int + 1 # 들어온 값에 1을 더해주는 함수
irb(main):005:1> end
=> :add
irb(main):006:0> add(a)
=> 1
irb(main):007:0> a
=> 0 # a의 값은 변하지 않았다.
# 변수의 값이 String일 때도
irb(main):008:0> string = 'a'
=> "a"
irb(main):009:0> def change(string)
irb(main):010:1> string = 'b'
irb(main):011:1> end
=> :change
irb(main):012:0> change(string)
=> "b"
irb(main):013:0> string
=> "a" # 원래 변수의 값은 변경되지 않았다.
# 배열은 어떨까?
irb(main):014:0> def add(arr)
irb(main):015:1> arr << 1
irb(main):016:1> end
=> :add
irb(main):017:0> arr = [0]
=> [0]
irb(main):018:0> add(arr)
=> [0, 1]
irb(main):020:0> arr
=> [0, 1] # 배열은 원래 변수의 값이 변경되었다!
왜 이런 차이가 발생하는걸까?
배열의 경우, 다른 타입보다 값과 값의 크기가 유동적이다.
Java와 달리 배열의 크기를 미리 지정해주지 않기 때문에, 메모리를 얼마나 할당해야 할 지 예측하기 어렵다.
그래서 객체를 호출할 때, 값 자체를 가리키기보다는 메모리상의 주소를 호출하는 것이 유리하다.
정확한 값을 가리키는 것이 아니고 주소를 가리키고 있기 때문에, 객체를 활용하는 도중에 값이 변할 수 있다.
이렇게 값이 아닌 주소를 가리키는 것을 Call by Reference라고 한다.
다른 예시를 보자.
irb(main):021:0> arr1 = [] # arr1은 빈 배열이다.
=> []
irb(main):022:0> arr2 = [0] # arr2는 0이 들어있다.
=> [0]
irb(main):023:0> arr1 = arr2 # 배열은 Call by Reference이므로, 주소가 같아진다!
=> [0]
irb(main):024:0> arr1 # 결국 arr1도 arr2의 주소값을 가지게 되어 들어있는 값도 동일해진다.
=> [0]
좀 더 쉽게 비유해서 설명하자면,
Call by Reference의 경우, 집 주소를 알려주는 것
Call by Value는 집에 뭐가 있는지 알려주는 것이라고 생각하면 된다. (=변수를 가져다 쓸 때, 주소가 아닌 값을 가져다 쓴다)
참고 사이트
http://ahimmelstoss.github.io/blog/2014/06/11/pass-by-value-vs-pass-by-reference-in-ruby/
http://luckyyowu.tistory.com/9
'Web development > Ruby' 카테고리의 다른 글
[Ruby] 함수를 동적으로 실행하기 (0) | 2019.06.18 |
---|---|
[Ruby] 인스턴스 변수 (0) | 2019.06.18 |
[Ruby] 생성자(Constructor) (0) | 2019.06.18 |
[Ruby] self란? (0) | 2019.06.18 |
[Ruby] symbol과 string의 차이점 (0) | 2019.06.18 |
댓글