[Scala] 함수의 상속 가능성을 deprecated 시키기

흠.... 블로거로 옮기고 나서 글을 쓰기 시작한 지 1년이 지나가는데, 이렇게 써도 되는지 고민되는 글은 처음이다. 사실 블로거로 옮기기 전에 폭파한 블로그가 2개인가 3개인가 있는데 당시에는 글을 써도 되는지 고민 없이 막 썼었다. 아는 게 없어 용감했었나 보다. 근데 어느 정도 아는 게 생기고 나니 혹시 나로 인해 잘못된 내용을 배워가는 사람이 있을까봐 최대한 정석에 가까운 내용만을 쓰려고 노력했다. 근데 이번에 쓸 글은 어떻게 봐도 편법에 해당하는 내용이다. 그래서 아래와 같은 경고로 글을 시작하겠다.

경고: 지금부터 설명할 방법은 권장되는 방법이 아닌 hacky한 방법입니다. 사용함으로 인해 생기는 문제는 책임지지 않습니다.


지난번 글에서 deprecated annotation을 이용해서 API를 변경하는 방법을 설명했었다. 이번에 설명할 내용은 function prototype은 변경하지 않고 클래스의 상속 가능성을 deprecate 시키는 것에 관한 내용이다.

Scala에는 sealed modifierfinal modifier를 이용해서 함수의 상속성을 제한하는 기능이 있다. 이 두 modifier에 대해서 간단하게 설명하면 sealed modifier는 다른 파일에서는 해당 클래스를 상속 못하게 막는 modifier이고, final modifier는 클래스를 상속 못하도록 하거나 함수의 override를 막아주는 modifier이다. 즉, API로 제공되던 클래스에 sealed나 final을 붙이거나 함수에 final을 붙이면 상속할 수 있던 클래스나 override할 수 있던 함수를 상속 불가능하게 만들게 된다. 이런 상황에서 쓰기 위해 설계되었던 것이 annotation이 deprecatedInheritancedeprecatedOverriding이다.

원래 deprecatedInheritancedeprecatedOverridingScala 2.10에 들어갈 예정이었다. 하지만 디자인 이슈를 결정하지 못하고 방황하는 사이에 2.10을 출시할 일정이 다가왔고 결국 구현체는 있지만, API로는 공개되지 않은 채 2.10이 출시되게 되었다. 따라서 정상적인 방법으로는 Scala 2.10이나 Scala 2.11에서 이 두 annotation을 사용할 방법은 없다.

하지만 상속 가능성을 deprecate 시키는 기능은 라이브러리 제작자라면 포기하기 아까운 기능이다. 가장 좋은 것은 이 기능이 Scala 라이브러리에 정식으로 반영되기를 기다리는 것이지만, 만약 어떻게든 지금 당장 사용하길 원한다면 다음과 같은 비정상적인 방법을 써야 한다.

현재 이 두 annotation은 scala packageprivate으로 되어있다. 따라서 scala라는 이름의 package object를 만들고 그 안에서 DeprecatedInheritanceDeprecatedOverriding라는 public 한 새로운 type을 만드는 것으로 scala package 밖에서도 두 annotation을 사용할 수 있게 된다.

하지만 시작부터 경고하며 시작했듯이 이는 hacky한 방식이다. 언제 이름이 바뀔지 모르고, 심지어 운이 없다면 언제 사라질지도 모르는 기능이다. 거의 편법에 한없이 가까운 방식이므로 사용할지 말지는 알아서 판단해서 선택해야 한다.


댓글

이 블로그의 인기 게시물

[C++] enum class - 안전하고 쓰기 쉬운 enum

Log Aggregator 비교 - Scribe, Flume, Fluentd, logstash

RAII는 무엇인가

[Python] cache 데코레이터로 최적화하기

[Web] SpeechSynthesis - TTS API