닷넷에 있는 익명 타입은 왜 제네릭이냐?

닷넷 개발자로 귀환하고 첫 닷넷글이네.

5년전의 MSDN 글을 보고 5년 후에 쓴 내가 조금 처량해 보이지만…

여태까지 익명 클래스 사용하는 법이야 당연히 많지만, 왜인지 해소를 해준 글은 본 적이 없다.
MSDN 글이 내 궁금증을 해소해주는 유일한 곳이긴 하다. 물론 MS에서 만들었으니 MSDN 에 올라는거야 당연하긴 하지만.

어쨌든, 내가 4년전에 익명 타입을 알아내는 방법 글을 올렸었다.
와.. 이때동안 난 자바했네 시발.

어쨌든 여기서 특징이 있다면…

  • CompilerGenerated 특성이 적용됩니다.
  • 제네릭 타입입니다. 의외네요.
  • 클래스 이름에 “AnonymousType” 라는 문구가 포함됩니다.
  • 클래스 이름 머릿말에 C# 의 경우 “<>”, VB의 경우 VB$ 로 시작됩니다.
  • 클래스는 public 이 아닙니다.

이렇게 기재되어 있다. 뭐 다른 이유야 구분짓고, 게다가 어자피 지역 변수니 internal 클래스는 이해 한다.
근데 왜 제네릭일까? 그래서 위 MSDN 블로그에 갔다.

자. 익명 클래스 하나 만들었다고 치자.

var x = new { A = "hello", B = 123.456 };

그리고 이걸 빌드 후 리플렉션 툴로 까보면 해괴망측한 클래스 정의가 나온다.

.class '<>f__AnonymousType0`2'< '<A>j__TPar','<b>j__TPar'>

여기서 익명 클래스의 특징이 나오는데, 바로 속성 수만큼 제네릭 타입 개수가 나온다는 것이다.
예를 들어 속성이 2개면, 제네릭에 들어갈 타입도 2개란 소리다.
MSDN에서는 컴파일 후 사용자 친화적인 코드로 표현하면 아래와 같은 코드가 나온다고 한다.

[CompilerGenerated]
internal sealed class Anon0<ta , TB>
{
    private readonly TA a;
    private readonly TB b;
    public TA A { get { return this.a; } }
    public TB B { get { return this.b; } }    
    public Anon0(TA a, TB b)
    { this.a = a; this.b = b; }
    // 여기에 object의 Equals, GetHashCode 와 ToString 메소드 덮겠지.
}

sealed 키워드까지 붙었다. 물론 굳이 저 클래스를 상속할 이유가 있겠는가?
그렇다면 첫번째 코드의 익명 클래스로 선언했을 때 컴파일된 클래스 결과물은 이렇다.

자, 그렇다면 익명 클래스에서 자신이 사용한 클래스를 적용한다면?
보통은 당연히 public이라면 어자피 제네릭에 들어가니 상관은 없다.
그런데… 이런 경우가 있다.

public class B 
{
    protected class P {}
}

B 클래스 내에 P 클래스가 있다. 당연히 P 클래스는 B 클래스와 B를 상속한 클래스 내에서만 접근 가능하다.
그런데 그걸 익명 클래스를 통해 밖으로 끄집어내기 시작한다.

class D1 : B
{
    void M() { var x = new { P = new B.P() }; }
}

class D2 : B
{
    void M() { var x = new { P = new B.P() }; }
}

이렇게 하면 어떻게 생성되느냐. 아래와 같다.

class D1 : B
{
    [CompilerGenerated]
    ??? sealed class Anon0 { public P P { get { ... } } ... }
    void M() { var x = new { P = new B.P() }; }
}

뭐… 그러고 보니 P 클래스가 공개적 접근이 안되는데 B의 M 메소드로 공개하려 하니 골치가 아프지 않은가.
그래서 아예 접근 못하는 클래스를 복사해 익명 클래스로 재생성한 꼴이 된다.
이 부분에 대해선 필자도 좀 더 공부해봐야 겠다.

자. 일단 이렇게 나온다. 간단히 정리하자면 익명 클래스는 속성 타입들의 제네릭 클래스다.
그 이유는 맨 위 MSDN 링크에서 설명했듯이 “성능”이다. 단순히 성능이 빨르다고 했다면 제네릭이 쓸 필요가 없지만,
제네릭은 박싱/언박싱으로 인한 타입 검증 과정을 줄여줌으로써 성능상 이득을 내는 건 닷넷 개발자라면 알 것이다.
바로 이런 원리를 익명 클래스에서도 적용했다고 보면 된다. 납득 ㅇㅇ?

그럼 이만 물러나겠다. 뿅.

composite / 2015년 4월 3일 / Piss Development / 0 Comments

MariaDB의 미래? io.js의 미래? 누가 앞서갈까?

이번 포스팅부터는 더이상 워드프레스의 좆같은 비주얼 에디터를 안쓰고 Github flavor markdown 을 쓰도록 하겠다.

오늘 인터뷰했을 때 뜬금포로 갑자기 마리아디비 할 줄 아냐고 물어봤다. 오랜만에 들어보는군. 마리아디비.

내가 설마 안써봤을까봐는 개뿔 SI 하면 MSSQL과 오라클 둘뿐인데 가뜩이나 MySQL조차 중소기업 쓴다고 무시하는 판국에 왠 마리아디비?

뭐 어쨌든. 사실 오늘 인터뷰 때문에 생각나서 포스팅 날린다.

MariaDB

오라클이 오픈소스에 대해 대하는 꼬라지는 참으로 개발자들 사이에서도 유명하다. 그들에게 오픈소스는 오로지 소스만 오픈되어 있을 뿐
쓰려면 돈내라는 것이다. 설령 개인적이 용도라 해도 말이다.

MySQL 이 썬이 먹고 그 썬을 오라클이 먹으면서 오라클의 오픈소스 정책을 따라가기 시작했고, 그들의 DB솔루션 노하우를 적용하여(?)
엔터프라이즈에서도 쓸 수 있는 대신 존나게 비싼 솔루션을 출시했다.
물론 기존 MySQL 에서는 커뮤니티 에디션으로 계속 쓸 수는 있다.

하지만 MySQL 핵심 개발자들은 이런 오라클의 자세와 애매한 라이센스 적용에 반발하여 몇몇이 나가서 만들었는데
그게 바로 MariaDB다.

MariaDB는 MySQL을 기반으로 작성되었으며, GPLv2 오픈소스이다.
상업용으로 쓰기엔? 지장없다. 소스 바꿀 일이 없다면 말이다. 아마 대부분은 그렇게 소스 바꿀 일 없이 쓸 것이다.

MariaDB의 자세한 역사까지 기재하기엔 내 손 아프니까 위키백과 가서 봐라.

현재 나온 버전으로는 MySQL과 동일한 시스템, 동일한 쿼리구조, 동일한 데이터 구조를 가지고 있다.
출발이야 MySQL에 반발해 시작했으니.

하지만 그 마리아디비도 곧 다른 노선을 탈 것이라는데. 아직 예정이긴 하지만.

위키백과와 구글도 MariaDB로 전환을 발표했다고는 했다. 적용 했는지 안했는지 알 길은 없지만.
아마 쓰겠지. 특히 구글이 오라클 때문에 존나 골치아플텐데 말이다.

하지만 업계 반응은 그닥…

특히 한국은 특히 더…

여전히 MySQL 5.5 를 쓰는 업체들이 주류일 것이고, 마리아디비는 호환 가능하다 해도 다들 안쓰는데 굳이 뭐 눈치보면서 쓸 이유가 있겠냐고 생각할 것이다.

물론 돈 들여서 개발 시작하는데 처음보는 기술을 도입한다는 건 여러가지 불투명을 안고 간다니 이해는 한다.

그렇다고 해서 마리아디비가 MySQL보다 뛰어나다고 증명할 만한 자료 찾기도 어렵거니와 도입에 성공해도 누구한테 자랑해야 할 지 모를테고.

어찌보면 그 해답은 MariaDB가 MySQL 과 다른 노선을 탈 때 나올 것이다.

io.js

엊그제 같은 일일 것이다. node.js 개발자들은 더이상 차기 버전에 대해 불투명하고 불안한 미래를 암시하기 시작했다.

joyent 는 대체 뭐하고 있는 것이길래 차기 버전을 내세우지 않는 것일까?

그리고 그들은 node.js 개발에서 손을 떼고, 새로 출발하기 시작했다.

이름하여 io.js 이다. 이렇게 된 역사를 자세히 기술한 블로그 포스트가 있으니 참고하도록.

io.js 는 ECMAScript 6 하모니를 가장 빨리 도입한 선진적 자바스크립트 프레임워크로 거듭나는 길을 목적으로 가고 있다.

물론 1월 15일 모습을 드러냈지만 node.js 와 똑같이 생각하기엔 아직까지는 멀었나 보다.

그들이 공식적으로 node.js 와 같이 출발할 것이라는 발표와 달리 이리저리 예외가 떨어져 호환이 안되고 있다.

물론 그들도 안정된 버전을 내놓지는 않고 당연히 알파 버전을 내놓긴 했지만.

솔직히 말해서 내가 io.js 의 미래를 점치기에는 시기가 너무 빠른 듯 하다.

하지만 io.js 는 마리아디비와는 달리 node.js 와 같은 노선을 탄다니 케이스가 다른 경우가 되겠다.

그리고 과연 개발자 커뮤니티의 중심의 민주적인 자바스크립트 프레임워크가 될 것인지는 안정된 버전이 나올 때까지는 지켜볼 일이 되겠다.

그래서?

미래가 뭐냐고? 물론 나도 뭐라 단정지을 수도 없다. 불투명하다고 하고 싶지만 이 글을 끝내기엔 나 존나게 원망할 것이다.

그래. 마음대로 생각해라.

어자피 오라클이야 마음 고칠 생각은 눈꼽만큼도 안보이지만, 조이엔트는 이 분위기를 의식했는지 좀 더 열려는 모습을 보이고 있다.

마리아디비처럼 경쟁체제로 가거나, io.js 처럼 상생체제로 가거나. 이제 이 둘의 미래가 과연

기업형 개발자와 커뮤니티형 개발자에게 이 둘의 미래로 어떤 영향을 줄 지가 내가 짚어보는 키 포인트라고 생각하고 있다.

이미 주사위는 굴러졌다. 경쟁과 상생의 아이콘. 오픈소스의 경쟁체제로 간 마리아디비, 오픈소스의 상생체제로 간 io.js!

개발자라면 이 둘의 행보를 절대 놓치지 말고 끝까지 계속 지켜보아야 한다. 당신이 개발자라면.

당신이 오픈소스를 지향하던 폐쇄적을 지향하던 내 알 바 아니다. 이 둘의 행보가 개발자들에게 어떤 영향을 줄 지가 관건이다.

놓치면 지는거다.

아. 인터뷰 얘기 나왔다고 영향 가나 신경쓸 필요 없어. 그사람은 날 원하지 않아서 신경 쓸 필요가 없거든.
내가 뭐 대단한 인력이라고 자신하긴 아직 뭐하지만 그렇다고 내가 꿇리는 개발자는 아니거든.
선배 개발자들이 원치 않았던 망할 프론트엔드를 내가 여태까지 도맡아 했기 때문에!

composite / 2015년 2월 6일 / Piss Development / 2 Comments

jQuery Paging Plugin

업데이트: 제이쿼리 페이징 플러그인 0.2.0 업데이트! 아래 설명 쌩까고 Github 으로 신속히 이동하라!

실무에 많이 쓰지만 은근히 빡센 페이징. 동적 페이징에 머리 짜매고 계신가? 여기 종결자가 있다.

jQuery Paging Plugin!

가볍다. 2KB밖에 안되며 gzip 압축 시 1KB도 안될 것이다.

빠르다. 페이징 외 쓰잘데기 없는 효과나 부가기능 따위는 없다.

쉽다. 한줄이면 페이징 초기화가 끝난다. 서버에서 불러와야 할 거는 현재 페이지와 총 페이지 수, 그뿐이다.

동적이던 정적이던 다 된다. 전통 방식 게시판이던 ajax 로 만든 게시판이던 입맛에 맞게 쓸 수 있다.

오픈소스다. 당신이 죽쓰던 밥쓰던 상관않는 MIT 라이센스다. 물론 더 좋은 방법 있으면 공유하는 것은 미덕!

사용법?

$(‘#paging’).paging({current:5,max:50}); //총 50 페이지 중 5 페이지로 시작하는 페이징을 불러올 것이다.

이거덕분에 프로젝트 잘되서 제작자한테 커피 한잔 쏘고 싶으면 ukjinplant at hotmail dot com 으로 연락해도 된다.

그럼 다운로드는?

소스(개발용) 다운로드 | 최적화(실무용) 다운로드 | 프로젝트 홈페이지

페이징 방식이 여러가진데 이 페이징 플러그인의 롤모델이 뭐인지 궁금하면 여기여기 를 클릭하여 확인해보라.

jQuery.Paging

jQuery를 위한 간단한 페이징.

사용법 : $('#paging').paging({max:50});

속성 :
item : 페이징 요소 태그명, 기본값 "a".
itemClass : 페이징 요소 중 페이지 수 CSS 클래스, 기본값 "paging-item".
itemCurrent : 현재 페이지를 나타내는 CSS 클래스이며 페이징 요소와 중첩됨, 기본값 "selected".
format : 페이지를 나타낼 내용, 기본값 "[%d]".
sideClass : 다음 또는 이전 버튼 CSS 클래스, 기본값 "paging-side".
next : 다음 버튼 내용. 기본값 "[{5}&gt;]" ("[>]")
prev : 이전 버튼 내용. 기본값 "[{4}&lt;]" ("[<]")
first : 첫 페이지 내용. 기본값 "[1&lt;&lt;]"
last : 마지막 페이지 내용. 기본값 "[&gt;&gt;{6}]"
length : 페이지 표시할 개수. 기본값 10.
max : 최대 표현할 페이지 수. 기본값 1.
current : 현재 페이지 정의. 기본값 1.
href : a 태그일 때 링크 주소를 정의. 기본값 "#%d"
append : true 설정 시, 기존 내용을 삭제하지 않고 페이징을 포함시킴. 기본값 false.
event : 기본 이벤트 활성화. 새로고침 없이 동적으로 페이징 초기화됨. ajax에 유용. 기본값 true.
>event=true 일 때 가능한 이벤트 정의.
onclick : 페이징 버튼 클릭 시 호출. false 반환 시 동적으로 페이지가 바뀌지 않음. 동적 페이징을 원하지만
                  href로 인한 링크 이동을 원하지 않을 경우 이벤트 메서드인 event.stopPropagation() 호출.
onprev : 이전 버튼 초기화 시 이벤트. 'this' 는 이전 버튼 요소를 가리킴.(plain DOM. not jQuery!)
onnext : 다음 버튼 초기화 시 이벤트. 'this' 는 다음 버튼 요소를 가리킴.(plain DOM. not jQuery!)
onitem : 각 페이지 버튼 초기화 시 이벤트. 'this' 는 각 페이지 버튼 요소를 가리킴.

치환자 (format,next,prev,href,first,last 속성 전용)
{0} = 클릭 시 페이지
{1} = 페이지 길이
{2} = 처음 페이지
{3} = 마지막 페이지
{4} = 이전 파트의 마지막 페이지
{5} = 다음 파트의 처음 페이지
{6} = 맨 마지막 페이지

판올림 내역
0.1.0 : 초기 버전
0.1.5 :
처음 페이지 및 마지막 페이지 추가. 내용에 치환자 적용 가능.
'append' 옵션 추가 : true 설정 시 기존 내용이 삭제되지 않고 포함됨.
{6} 치환자는 마지막 페이지(max 값과 동일) 를 가리킴
0.1.6 : first 또는 last 내용에 false 설정시 만들지 않도록 기능 추가.

composite / 2012년 10월 11일 / Piss Development / 11 Comments