rails 프로젝트를 하다가 객체를 만들어 concat을 사용하는 메소드를 실행 시키는데
초기 config값을 가지고 있는 변수의 값이 자꾸만 변하는것이다. 예를 들면
class Test
CONFIG = "1111"
def print
test1 = CONFIG
test1.concat("2222")
puts test1
puts CONFIG
end
end
이런 클래스가 있다고 치자 이때 CONFIG 변수에 저장된 값을 test1에 저장하고
test1에 문자열을 더하고 싶어 concat을 하여 2222를 추가 하였다. 그리고 test1과 CONFIG를 출력하였다.
이때 출력값은 무엇이 나올까?
놀랍게도 두개의 출력값다 기존에 있던 1111값과 concat한 2222를 한 값인 11112222가 나오게 된다.
사실 이건 concat의 문제는 아니다.
다만 내가 concat을 사용할때 생긴 문제이기 때문에 예를 이것으로 든것 뿐이다.
그래서 왜 이런 일이 생긴것인지에 대해서 찾아보았다.
먼저 결론부터 말하자면 루비에서 변수는 객체 이기 때문에 이런 현상이 생긴것이다.
(읽기 귀찮으면 밑에 3줄요약만 읽어도됨)
루비는 모든것이 객체인가?
이 현상의 원인은 루비의 자체에 있는데
루비는 모든것이 객체이다. 그래서 정말 변수도 객체인것인가 해서 찾아보았다.
Is variable is object in ruby?
결론적으로 루비는 call by references 방식을 가지고 있어서, 주소값을 복사해주는게 아니라 value 가 주소값이라서 주소값을 복사하는 것이다. 예를들면
a = 1 <-- a가 가리키는 객체(1)의 주소값 111
b = a <-- a가 가리키는 객체(1)의 주소값 111을 b에 저장
puts b <--- b가 가리키는 객체(1)의 주소값 111에 저장된 값 출력
이렇게 된다는 것이다.
그래서 b의 값을 변경하면 a의 값도 변경이 되는 거다.
루비에서 변수의 값(객체의 값) 복사 하기
위에서 루비의 변수는 객체의 주소값을 가지고 있기 때문에 복사당한 대상의 변수값도 변경이 될수있다고 했다.
하지만 나는 변수의 값(객체의 값)을 복사해서 사용하고 싶다.
이럴때는 clone이라는 함수를 사용하면된다. 예를들면
test = [1,2,3]
b = a.clone
b.concat 4
puts a
puts b
를하면 a는 123이 출력되고 b는 1234가 출력된다.
더 자세하게 알고 싶다면 이곳 에서 cloning objects라는 부분을 보면된다.
결국 루비에서 변수는 객체를 가지고 있는 것이고, 변수끼리 값을 전달할때 변수에 저장된 값은 객체의 주소값을 가지고 있기 때문에 주소값이 전달이 된다. 그러므로 변수의 값(객체의 값)을 복사해서 사용하고 싶다면 clone 메소드를 사용하면된다.
3줄 요약
1. 루비에서 변수는 객체를 가리키(point)기 때문에 주소값을 가짐
2. 그래서 변수 복사를 할때 call by value 방식이지만 주소값이 넘어가서 메모리를 공유하게됨
3. 이게 싫으면 clone메소드를 쓰면됨
참고
http://stackoverflow.com/questions/1872110/is-ruby-pass-by-reference-or-by-value
http://stackoverflow.com/questions/22827566/ruby-parameters-by-reference-or-by-value/22827949#22827949
http://stackoverflow.com/questions/8382173/ruby-is-variable-is-object-in-ruby
https://rubymonk.com/learning/books/4-ruby-primer-ascent/chapters/39-ruby-s-object-model/lessons/132-cloning-and-freezing-objects
'ruby on rails' 카테고리의 다른 글
레일스 캐시 지우기 (0) | 2016.05.04 |
---|---|
rails 에서 갑자기 mysql2에러가 날때 (0) | 2015.09.16 |
rails+dragonfly 사용할때 sh: convert: command not found 에러해결 (0) | 2015.07.01 |
rails+nginx+passenger development 모드사용하기 (0) | 2015.06.30 |
rails+nginx+passenger 트러블슈팅 (0) | 2015.06.30 |
WRITTEN BY
- rabbbit
필기