[ECMAScript 6] class 선언하기

JavaScript는 훌륭한 객체 지향 언어다. 하지만 프로토타입 기반 객체지향 이라는 독특한 개념과 특유의 verbose한 문법 때문에 다른 언어에서 넘어온 사람들은 쉽게 적응하지 못하였고, 객체 지향스럽지 않은 코드를 작성하였다. 그럼에도 프로토타입은 다른 객체 지향 언어가 제공하는 class 에 비해서 더 유연한 확장성 지원하기 때문에 많은 JavaScript 개발자들은 class 가 필요 없다는 입장을 고수해왔다. 하지만 프로토타입이 코드를 verbose 하게 만들고, 가독성을 떨어뜨린다는 주장은 꾸준히 제기되었고, 결국 ECMAScript 6에 드디어 class 키워드가 추가되어 보다 쉽게 객체 지향적 코드를 작성할 수 있게 되었다. 여기서 중요한 것은 class 키워드가 ES6에 추가되었다고 해서 클래스 기반 객체지향 이라는 개념이 추가된 것은 아니라는 것이다. ES6도 여전히 프로토타입 기반의 객체 지향 언어이다. class 는 프로토타입 기반 객체를 만드는 syntactic sugar 일 뿐이다. 즉, 위와 같은 코드는 ES5를 기준으로 보면 아래와 같이 해석된다. 1) class 스타일의 간결성과 prototype 의 유연성을 동시에 갖기 위한 선택이었다. 1) 완전히 일치하는 것은 아니다. ES5에는 생성자로 쓸 수 없는 함수 가 존재하지 않기 때문에 method를 완벽히 재현할 수 없다.

[ECMAScript 6] property 선언하기

property 란 사용하는 코드는 member data에 접근하듯이 사용하지만 실제로는 함수가 호출되도록 하는 프로그래밍 언어의 기능을 말한다. C#, Python, Ruby 등 객체를 중요시하는 언어에는 대부분 존재하는 기능이며 당연히 기존의 JavaScript에도 있었다. 하지만 Object.defineProperties 함수를 이용해야 해서 코드가 복잡해진다는 문제가 있었다. ES6에서는 property를 쉽게 선언할 수 있는 문법을 도입하였다. 메소드의 이름 앞에 get 이나 set 을 붙이는 것만으로 property를 선언할 수 있다.

[ECMAScript 6] method 선언하기

ECMAScript 5에는 메소드에 해당하는 개념이 없었다. 그저 함수가 first-class citizen 이기 때문에 객체의 멤버변수로 함수를 할당하는 방식으로 메소드를 만들었다. ECMAScript 6에는 method를 만들기 위한 문법이 추가되어 메소드를 선언할 수 있게 되었다. 이는 크게 보면 ES5에서 사용하던 함수를 멤버변수에 할당하는 방식과 다를 것 없다. 하지만 사소한 부분에서 약간 다르다. 메소드는 이름 을 가지지만 new 를 통해서 객체를 만들어낼 수 없다. 이는 메소드만이 가지는 특징이다. 일반적인 함수는 모두 new 를 통해 객체를 만들어낼 수 있다. 반면에 람다 함수 는 new 를 통해서 객체를 만들 수 없지만, 이름을 가지지 않는다.

[잡담] 대수적 자료형과 정적 타입 분석이 필요하다

트오세 출첵 이벤트 지금 무제한으로 수령되는 버그 있는데 버그 원인이 오타 다 pic.twitter.com/0YIS6YSIw1 — Enpi (@Enpi_) 2016년 1월 7일 그랬다면 최소한 위와 같은 버그는 막을 수 있다.

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

C++ 03 까지의 enum 은 여러 가지 문제를 가지고 있었다. 그래서 그 문제들을 해결하기 위해 C++ 11은 enum class 라는 것을 새로 만들었다. 이제부터 기존의 enum 에 어떤 문제가 있었고, 이것을 enum class 에서 어떻게 해결하였는지 살펴볼 것이다. 우선 기존의 enum 은 전방 선언할 수 없었다. 그 이유는 enumerator에 어떤 값이 들어있을지 알 수 없으면 그 크기를 정할 수 없기 때문 이다. 하지만 enum class 는 underlying type을 명시하지 않으면 int 타입과 같은 크기의 변수로 선언되고, int 값 안에 들어가지 못할 값을 지정하면 컴파일 에러를 발생시킨다. 만약 int 를 벗어난 범위의 값을 사용하고 싶다면, underlying type을 명시해주어야 한다. 기존 enum 의 또 다른 문제는 enumerator의 이름의 범위가 한정되지 않는다는 것이다. 예를 들어 아래와 같은 코드를 보자. IO 함수의 결과와 Parse 함수의 결과를 enum 으로 표현해 보았다. 하지만 이 코드는 컴파일되지 않는다. IOResult 의 Error , Ok 가 ParseResult 의 Error , Ok 와 겹치기 때문이다. 이를 해결하기 위해서는 다음과 같이 enumerator의 이름을 다르게 하거나 아래와 같이 namespace 를 이용해야 했다. 하지만 enum class 는 enumerator의 이름이 enum class 안으로 한정되기 때문에 이런 복잡한 과정이 필요 없이 그저 enum class 를 선언하여 사용하면 된다. 무엇보다 기존 enum 의 가장 큰 문제는 정수형 변수로 암시적으로 변환되는 약 타입(weak type) 변수라는 것이다. 하지만 enum class 는 정수형 변수로 암시적 변환이 되지 않는다. enum class 를 정수형 변수처럼 사용하려고 하면 컴파일 에러를 발생시킨다. 만약 정수형 변수로 사용하고 싶으면 static_cast 를 이용해

빈 객체 크기는?

위와 같은 클래스를 생각해 보자. 보통 empty 클래스라고 부르는 이 클래스는 아무런 내부 변수를 가지고 있지 않다. 그렇다면 이 empty 클래스의 크기는 얼마일까? 언뜻 생각해보면, 아무런 멤버 변수가 없으니 그 크기가 0일 것 같다. 하지만 Java, C#, C(이 경우는 struct), C++ 어떤 언어에서도 0이 나오지 않는다. 이는 두 다른 객체가 같은 주소를 가르치는 일이 없도록 하기 위한 것 이다. empty 클래스는 보통 32 bit 환경에서는 1 바이트 크기를 가지고, 64 bit 환경에서는 2 바이트 크기를 가진다. 하지만 정확히 어떤 값이 나오는지는 알 수 없다. 스펙에 따르면 크기가 0이 되지 않기만 하면 된다. 정확한 크기는 구현체에 따라서 다르다.

Null Object pattern - null 사용하지 않기

이미지
C#, Java 등 현대의 많은 언어는 객체를 레퍼런스로 다룬다. 그리고 모든 레퍼런스는 nullptr 이 될 수 있는데, 이 nullptr 은 컴파일 타임에 검사할 수 없는 런타임 에러인 NullPointerException 을 일으킨다. 그래서 nullptr 은 최대한 조심해서 사용해야 하며, nullptr 이 될 수 있는 변수는 사용하기 전에 반드시 nullptr 인지 검사해야 한다. 하지만 변수를 사용하기 전에 매번 null check를 하는 코드는 예쁘지 못하고 실수하기 쉽다. 이런 문제를 해결하기 위해서 나온 것이 null object pattern이다. 하지만 null object pattern은 그리 널리 사랑받는 패턴은 아니었다. 사용하기 불편한 여러 가지 부분이 있어 오히려 안티 패턴으로 불리기도 했다. 대체재가 없어서 꼭 필요한 경우에만 어쩔 수 없이 사용하는 패턴이었다. 하지만 이제는 그마저도 사용할 필요가 없다. null object를 사용할 부분은 전부 Option 모나드 로 대체할 수 있다. Option 모나드를 사용하는 것이 훨씬 사용하기 쉽고, 문제도 적다. 그래서 필자는 null object pattern을 사용해야 할 곳은 대신 Option 모나드를 사용하는 것을 추천한다. 그런데도 null object pattern을 설명하는 이유는 어쨌든 null object pattern이 nullptr 이 가지는 문제를 해결하고자 나온 패턴으로 과거 여러 프로젝트에서 쓰였기 때문에, 알고 있는 것이 기존의 코드를 읽는 데 도움이 되기 때문이다. 결코, 사용을 권장하기 위해서는 아니다. null object pattern은 아무것도 안 하는 객체(null object)를 제공함으로써 NullPointerException 을 피하는 패턴이다. 조금 더 구체적으로는 nullptr 를 써야 하는 클래스의 부모 되는 interface를 구현하는 null class를 만들고, 그 클래스의 객체를 nullptr 대신해서 사용하는

이 블로그의 인기 게시물

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

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

RAII는 무엇인가

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

[Web] SpeechSynthesis - TTS API