encapsulation and information hiding
class MyClass
def initialize
return @test = 500
end
end
ob = MyClass.new
p ob.@test # error
위의 코드는 에러가 발생한다. 인스턴스 변수에 직접 접근하려 했기 때문이다. 내부 데이터에 접속하기 위해선 반드시 메소드를 사용해야한다. 이러한 접근방식의 장점 중 하나는 데이터에 대한 통제가 가능하다는 것이다. 예를 들어 보자.
class MyClass
def initialize(num)
return @test = num
end
def test
if @test < 0
val = 0
else
val = @test
end
return val
end
end
num = 500
ob = MyClass.new(num)
p ob.test # 500
num2 = -500
ob2 = MyClass.new(num2)
p ob2.test # 0
위의 코드는 인스턴스 변수인 test가 음수의 값을 가질 수 없도록 하고 있다. 외부인이 직접 내부 데이터인 @test에 접근할 수 없을 뿐더러 그 값도 코드의 작성자인 '나'로 인해 컨트롤 된다.
또한 메소드 안에서 매개변수에 이런 저런 변경을 가하더라도 메소드 바깥에 있는 변수, 위의 예제에서는 num, num2, 에는 아무런 영향을 미치지 않는다.
하지만 이러한 인포메이션 하이딩만 빋고 메소드 작성시 주의를 기울이지 않는다면 문제가 생길 수 있다. 아래의 코드를 보자.
def stringProcess( aStr, anotherStr )
myStr = aStr.capitalize!
anotherStr.reverse!.capitalize!
myStr = myStr + " " + anotherStr.reverse
return myStr
end
str1 = "hello"
str2 = "world"
str3 = stringProcess( str1, str2 )
puts( "Return value is #{str3}" )
puts( "Value of args is #{str1} #{str2}" )
# -------실행결과------------
Return value is Hello worlD
Value of args is Hello Dlrow
str1과 str2의 값이 바꼈다! 어떻게 된 일인가? 범인은 바로 !가 붙은 메소드이다.
capitalize!와 reverse!는 값을 영구히 바꿔버린다.
test = "hello"
puts( test.object_id ) # 70333487383140
test.reverse!
puts( test ) # olleh
puts( test.object_id ) # 70333487383140
위의 코드에서처럼, test는 여전히 같은 object이지만 값이 영구히 바뀐 것을 알 수 있다.
저 위의 str1과 str2의 값도 마찬가지였다. 각 변수가 처음 선언될 때의 값은 메소드를 거치며 영구히 변경되어버렸다.
만약 다른 개발자가 와서 새로운 메서드를 작성하고 있다고 가정해보자. 그 때 저 변수들을 그대로 가져다 쓰기로 마음먹었다면 어떻게 되겠는가? 당연히 에러가 날 것이다. 내가 매개변수로 넘기고자 한 변수의 값은 'hello'와 'world'였지만, stringProcess라는, 다른 개발자가 작성해놓은 메서드를 거치며 값이 영구히 변경되었기 때문이다.
메소드를 작성할 때 인포메이션 하이딩만 믿고 생각없이 코드를 짜지 말아야 할 이유다. 물론 대부분 이러한 코드를 짤 일은 극히 드물것이다. 하지만 그럼에도 예외가 있기 마련임을 명심할 필요가 있겠다.
** Udemy의 「Advanced Ruby Programming: 10 Steps To Mastery」를 보고 작성하였습니다.
'TIL > RUBY' 카테고리의 다른 글
루비 구조와 해석(interpretation) (0) | 2021.03.05 |
---|---|
exception error handling (0) | 2021.01.24 |
Argument (0) | 2020.12.10 |
class method (0) | 2020.12.09 |
Symbol (0) | 2020.12.05 |