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

흠.... 블로거로 옮기고 나서 글을 쓰기 시작한 지 1년이 지나가는데, 이렇게 써도 되는지 고민되는 글은 처음이다. 사실 블로거로 옮기기 전에 폭파한 블로그가 2개인가 3개인가 있는데 당시에는 글을 써도 되는지 고민 없이 막 썼었다. 아는 게 없어 용감했었나 보다. 근데 어느 정도 아는 게 생기고 나니 혹시 나로 인해 잘못된 내용을 배워가는 사람이 있을까봐 최대한 정석에 가까운 내용만을 쓰려고 노력했다. 근데 이번에 쓸 글은 어떻게 봐도 편법에 해당하는 내용이다. 그래서 아래와 같은 경고로 글을 시작하겠다. 경고: 지금부터 설명할 방법은 권장되는 방법이 아닌 hacky한 방법입니다. 사용함으로 인해 생기는 문제는 책임지지 않습니다. 지난번 글 에서 deprecated annotation 을 이용해서 API를 변경하는 방법을 설명했었다. 이번에 설명할 내용은 function prototype 은 변경하지 않고 클래스의 상속 가능성을 deprecate 시키는 것에 관한 내용이다. Scala에는 sealed modifier 나 final modifier 를 이용해서 함수의 상속성을 제한하는 기능이 있다. 이 두 modifier에 대해서 간단하게 설명하면 sealed modifier는 다른 파일에서는 해당 클래스를 상속 못하게 막는 modifier이고, final modifier는 클래스를 상속 못하도록 하거나 함수의 override를 막아주는 modifier이다. 즉, API로 제공되던 클래스에 sealed나 final을 붙이거나 함수에 final을 붙이면 상속할 수 있던 클래스나 override할 수 있던 함수를 상속 불가능하게 만들게 된다. 이런 상황에서 쓰기 위해 설계되었던 것이 annotation이 deprecatedInheritance 과 deprecatedOverriding 이다. 원래 deprecatedInheritance 와 deprecatedOverriding 는 Scala 2.10에 들어갈 예정 이었다. 하지만 디자인 이슈를

[Scala] deprecated annotation - 호환성을 보장하며 API 수정하기

크게는 구조의 변경을 위해서부터, 작게는 오타 수정까지 API를 수정할 일은 많이 있다. 하지만 API를 변경하는 것은 복잡하고, 오래 걸리고, 어려운 일이다. deprecated API를 변경한다고 해서, 전에 사용하던 API를 바로 지우면, 그전 API를 사용하는 사람들이 급격하게 코드를 바꿔야 한다. 반대로 지우지 않고 2개의 API를 둔다 면, 전 API를 사용하던 사람이 코드를 고치지 않을 뿐 아니라, 새로 코드를 작성하는 코드에도 사용하지 않아야 하는 API를 사용하게 돼서 결국 2벌의 코드를 유지 보수해야 한다. 이런 상황에서 사용하는 것이 deprecated annotation 이다. 위의 예제와 같이 deprecated annotation을 붙이면 해당하는 함수를 호출하는 코드를 컴파일할 때, 컴파일은 되지만 경고 메시지를 출력해준다. 게다가 내부적으로 Java의 Deprecated annotation 을 더해주기 때문에, 자바 코드에서 호출해도 경고 메시지가 출력된다. 사실 Scala의 deprecated annotation은 Java의 Deprecated annotation과 에러 메시지와 version을 정해줄 수 있다는 것 외에는 큰 차이가 없다. 그렇기에 Scala는 다른 annotation을 더 지원한다. deprecatedName 함수의 type signature 를 바꾸는 일만큼, 함수의 type signature는 그대로 두고, 함수 인자의 이름만 바꿔야 하는 일도 많이 생긴다. 그 이유는 다양한데 기존에 사용했던 이름이 부적절했기 때문일 수도 있고, 함수의 동작이 바뀌면서 넘겨야 하는 인자가 변했지만, 우연히 타입은 같은 경우였을 수도 있다. Java는 named parameter 를 지원하지 않기 때문에 인자의 이름만 변경하는 경우가 문제 되지 않는다. 하지만 Scala처럼 named parameter를 지원하는 언어에서는 함수의 이름을 바꾸는 것도 문제가 될 수 있다. 이럴 때 사용하기 위한 것

Facade pattern - 간단한 인터페이스 만들기

이미지
퍼사드 패턴 이란 복잡한 서브 시스템에 하나의 레이어를 씌워서 복잡한 시스템을 사용하기 쉽게 만드는 방식을 말한다. 퍼사드 패턴은 레이어를 하나 추가하지만, 이 레이어는 추상화가 목적이 아니다. 어디까지나 사용하기 쉽게 만드는 것이 목적이다. 그래서 보통 퍼사드의 인터페이스는 매우 간단한 모습을 가진다. https://en.wikipedia.org/wiki/File:Example_of_Facade_design_pattern_in_UML.png 퍼사드 패턴의 대표적인 사용처는 로그 API다. 로그를 그대로 STDOUT 에 출력할 수 도 있고 어딘가에 저장할 수도 있다. 저장하는 것도 로컬에 있는 파일에 기록을 남길 수도 있고, 데이터 베이스에 파일을 저장할 수도 있고, 그 이외의 방식으로 로그를 저장할 수도 있다. 즉, 만약 파일에 저장한다면 적절하게 파일 포인터를 관리해야 하고, 데이터 베이스에 저장한다면 그 connection을 적절하게 관리해야한다. 게다가 로그를 저장하는 것도 IO로 인한 병목을 피하기 위해 일정 시간 혹은 일정 갯수의 로그를 모았다가 저장할 수 도 있다. 만약에 모았다가 저장한다면, 저장할 조건을 만족시키지 않았더라도 프로세스가 종료되기전에 저장을 완료해야 한다. 이런 조건들을 사용자가 일일히 챙겨가며 로그를 저장하는 것은 귀찮은 일이다. 그래서 Logback 같은 API에서는 back-end가 어떻게되든 상관 없이 필요한 back-end를 사용하도록 초기화해주면, 그 뒤로는 같은 인터페이스로 기록을 남길 수 있게 해준다. 전에 소개한 적 있던 Pluggable한 log aggregator인 fluentd 의 경우도 퍼사드 패턴을 사용한다. Input plug-in, Buffer plug-in, Output plug-in은 모두 간단한 인터페이스만을 요구한다. 덕분에 fluentd의 engine은 간단한 코드를 유지할 수 있고, 간단하게 원하는 back-end를 선택해서 동작을 바꿀 수도 있다. 본 글은 CC BY

file URI와 same-origin policy

modern web browser에는 보안을 위한 여러 가지 기능들이 들어있다. 그중 가장 대표적인 기능이 same-origin policy 다. same-origin policy 덕분에 (개발자 입장에서는 약간 짜증 나기는 하지만) 특별히 신경을 쓰지 않아도 보안에 관해 상당히 많은 부분을 커버할 수 있다. same-origin policy의 원칙은 매우 간단하다. 내 사이트가 다른 사이트에서 호스팅 되는 리소스에 의존하는 것을 금지해서, 내 사이트가 오염되거나 다른 사이트에 의해 공격당하는 것을 막는 것이다. same-origin인지 결정하는 것은 매우 간단한데 프로토콜, 호스트, 포트가 같은 URI 를 same-origin이라고 판단한다. 요새는 대부분 개인 서버와 개인 도메인을 사용하기 때문에, 프로토콜과 포트까지 같은지 판단하는 것은 너무 빡빡한 기준이라고 생각할 수도 있지만, 워크스테이션이나 공용 서버에서 작업하는 일도 많다는 것을 생각하면 포트와 프로토콜까지 고려하는 것은 역시 상식적인 판단이라고 할 수 있다. 브라우저에서 많이 쓰이는 http나 https에서는 이 규칙이 상식적이라고 할 수 있다. 문제는 file URI 에서의 동작이다. file URI에 대해서는 어떤 URI를 same-origin이라고 할 것인지 정해진 것이 없고, 브라우저마다 알아서 자신이 옳다고 생각하는 방식으로 구현했다. 우선 오페라 는 file URI도 다른 URI와 같은 정책으로 처리한다. 따라서 file URI로 접근한 페이지에서는 읽기 권한이 있는 모든 파일을 읽어서 리소스로 활용할 수 있다. 어차피 파일은 OS가 access list로 보호하고 있으니, 로컬 파일에 대한 보안을 OS에 맡겨 버린 것이라고 할 수 있겠다. 약간 무책임한 것 같지만, 오페라의 구현이 가장 웹서버 없이 웹 페이지를 테스트하기 편한 구현이다. 반면 크롬 은 modern browser 중에 가장 빡빡한 규칙을 적용한다. 크롬에서는 file URI로 들어오는 요청에 대해 무조

WebGL 공부 시작

나는 그래픽스 관련해서는 모든 것을 야매로 배웠었기 때문에, 전반적으로 기초가 없다. 이게 나름대로 꽤 스트레스였다. 하지만 천성적으로 게을러서, 계속 언젠가는 제대로 공부해야 한다고 생각만 하고 미루기만 했다. 그러다가 문득 이렇게 미루기만 하면 언젠가 후회할 날이 올 것 같아서 바로 공부를 시작하기로 했다. 우선 공부할 그래픽스 라이브러리는 OpenGL 로 정했다. 모바일 시장이 있어도 역시 많이 쓰이는 것은 Direct3D 고, 게다가 apple에서는 metal 이라는 새로운 그래픽스 라이브러리를 발표해서 OpenGL의 입지가 더 줄어들 것이라고 한다. 하지만 나는 이번 목표가 당장 어딘가에 써먹기 위한 것을 배우기 위한 것이 아니라 기본적인 것을 배우기 위한 거라서 뭘 하더라도 상관없었다. 사실 지금 내 윈도우 pc는 망가지고, iMac은 이제 개발용으로 쓰기에는 성능이 너무 나빠서 별 다른 선택의 여지가 없었다. OpenGL API 구현체도 platform 별로 여러 가지 구현체가 있다. 나는 그중에서 WebGL 을 공부하기로 했다. 특별히 web platform에서 작업할 일이 있었던 것은 아니지만, 리눅스 환경에서 OpenGL로 코딩하려면 리눅스 드라이버를 수동으로 재 설치해야 하는 경우가 많아서 브라우저만 있으면 바로 작업 가능하다는 특징은 WebGL의 큰 장점이라고 생각한다. 그리고 무엇보다도 WebGL Inspector 라는 좋은 디버깅 툴이 있다는 것은 WebGL의 가장 큰 장점이라고 생각한다. 리눅스에서 OpenGL 개발 환경을 구성할때는 개발 환경 자체를 준비하는 것도 귀찮지만, 디버깅 환경을 구성하는 것이 진짜 귀찮다. 그래픽 드라이버 버전에 따라서는 아예 디버깅할 수 없어서 무조건 실행시켜보는 수밖에 없는 경우도 있다. 하지만 브라우저의 플러그인 형식으로 설치 가능한 WebGL Inspector를 사용하면, 프레임을 멈추거나 속도를 조정할 수도 있고, 어떤 콜이 불렸는지, array buffer나 element arr

도메인 이전했습니다.

며칠 전에 말했던 대로 https://blog.seulgi.kim 으로 이전했습니다. 기존 도메인인 blog.seulgik.im으로 접속해도 리다이렉트 되겠지만, 해당 도메인은 앞으로 사용할 예정이 없어서 2016년 6월(!) 이후로는 접속이 안 될 겁니다.

조만간 도메인 이전합니다.

기다리고 기다리던 seulgi.kim을 드디어 샀네요. 조만간에 blog.seulgi.kim 으로 이전합니다. 바로 이전하고 싶은데 blogger가 동시에 여러 개의 cname을 지원하지 않네요. 요새 너무 바빠서 시간 나면 리다이렉트 페이지 만들고 그때가서 이동할게요.

이 블로그의 인기 게시물

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

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

RAII는 무엇인가

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

[Web] SpeechSynthesis - TTS API