2010년 4월 8일 목요일

private 멤버는 underscore를 suffix로 주는 코딩 스타일

멤버 필드의 이름 뒤에 underscore(_)를 붙이는 네이밍 방식을 구글 코딩 스타일에서 본 적이 있는데 왜 그게 좋은지 궁금했었다. 갑자기 또 생각나서 찾아봤는데 가독성 때문이란다.

"Indicating class scope by using underscore makes it easy to distinguish class variables from local scratch variables. This is important because class variables are considered to have higher significance than method variables, and should be treated with special care by the programmer. ... (중략)... latter is recommended because it seem to best preserve the readability of the name."

출처 :
http://stackoverflow.com/questions/1630412/is-using-underscore-suffix-for-members-beneficial

2010년 4월 6일 화요일

같은 AIR 애플리케이션 여러번

살다보면 같은 AIR 앱을 여러번 띄우고 싶은 경우가 있다.

그 경우 C:\Program Files\MyApp\META-INF\AIR 에 있는 application.xml파일의 <id /> element의 text 값을 바꿔주면 된다. 새로 앱을 띄울때마다 바꿔줘야 하기 때문에 프로그래밍 코드로 처리해 주는 것이 좋은데, 다행히 MyApp 안의 디렉토리는 제어권한이 있다.

2010년 4월 3일 토요일

AS3.0 Package 외부에 클래스 정의하기

"one class in each file can be made available to code that is external to that file. In other words, only one class in each file can be declared inside a package declaration. You must declare any additional classes outside your package definition, which makes those classes invisible to code outside that source file. The name of the class declared inside the package definition must match the name of the source file."

추가적인 클래스들을 패키지 밖에 정의할 수 있고 이렇게 정의된 클래스는 소스코드 밖에서는 보이지 않게 된다.

2010년 4월 2일 금요일

Unable to load config info from /usr/local/ssl/openssl.cnf

OpenSSL을 사용하는데 다음과 같은 에러가 났다.

"Unable to load config info from /usr/local/ssl/openssl.cnf"

이는 openssl.cnf의 위치가 지정되어있지 않아서 생기는 에러다.

에러가 나는 명령 끝에 -config "openssl.cnf의 위치"를 입력하면 해결된다.

2010년 3월 25일 목요일

AIR NativeWindow에서 Window 얻는 방법

AIR에서 activeWindow(active 상태의 윈도우)에 Alert을 띄워야 했다.

우선 Alert을 특정 Sprite의 자식으로 띄우는 방법은 다음과 같다.

Alert.show("", "", 4, 자식);

AIR에서 여러 대화창 중에 가장 상위에 존재하는 대화창에 Alert을 띄우려면

가장 상위의 대화창를 얻어서 위의 Alert의 네 번째 인자로 주면 된다.

가장 상위의 대화창을 얻어서 Sprite를 또 얻으려면 아래처럼 하면 된다.

((NativeApplication.nativeApplication.activeWindow.stage.getChildAt(0) as WindowedSystemManager).document as Sprite)

이건 뭐..

2010년 3월 7일 일요일

중독성 퀴즈게임 과로사

내가 제일 좋아하는 스테이지

다 풀었다.


과로사라는 게임이다.  회사원으로 보이는 주인공을 일로부터 해방(?)시켜 주는 것이다. 과로사1을 받아다가 풀었는데 퀴즈 푸는 재미가 쏠쏠하다.

2010년 2월 28일 일요일

Method Chaining

메소드가 자신(this)을 리턴하여 메소드에 메소드를 연결하며 호출할 수 있게하는 기법의 정확한 이름은 Method Chaining이다(http://martinfowler.com/dslwip/MethodChaining.html). 이전 포스트에서 DML-style operations라고 표현해도 되나 의문을 가졌었는데 잘못된 것이다. Java 7에서는 이 기법이 아주 이디엄이 돼버렸는데 Chained Invocation으로 불린다.

 

소트웍스 앤솔러지를 보면 이와 비슷한 방법으로 마틴 파울러가 ruby 위에서 DSL을 구축해 나가는 과정의 글이 나온다. method chaining을 사용하여 문제영역을 표현하는 방법을 보이는데 언어위에서 DSL을 구축하는 방법으로 쓰이는 것이다(물론 ruby라는 동적 언어의 장점을 사용하여 DSL을 구축하는 방법이 추가되어 있다). 병특 시절 실용주의 프로그래머를 보면서 DSL에 매력을 느꼈었다. 그런데 좋긴 좋은데 언어 위에 다른 언어를 만들어 낸다는 내용을 읽으며 뭔소린가 하던 기억이 난다. 그리고 대신 Lex & yacc 펼쳤다는 ㅎ.

 

묵혀둔 질문 몇 개가 한 번에 해결됐다.

GUI 한 번 하려다가.

인터넷에서 찾아보고 결론은 shoes 괜찮아 보인다였다. 그러나 모든 사이트가 열리지 않자 이것 저것 찾아본 결과 shoes를 제작한 _why가 활동을 접었다는 내용을 찾았다. 이미 오래된 이야기였다.

 

On 19 August 2009, his online presence was drastically truncated; his accounts on Twitter and GitHub were shut down, along with many of his personally maintained sites. His projects have since been collected and centralized on the whymirror GitHub account. -- [출처 : 위키피디아]

 

 

_why가 트위터를 지우기 전에 마지막으로 작성했다던 내용

 

If you want your programming to be remembered, make a game.
Everything else you write will be obsolete in a year, and won't run on available systems in two or three.
Yet people spend huge amounts of energy on systems to keep games alive.
 
programming is rather thankless.
you see your works become replaced by superior works in a year.
unable to run at all in a few more. -- [출처 : kldp]

 

결국 Tcl/Tk 를 깔고 쓰고있긴 한데 씁쓸하다.

어머 5등

 

깜짝이야.

2010년 2월 16일 화요일

2010년 1월 28일 목요일

Flash Builder, Flex Builder에서 Task plugin 사용하기

google reader를 켰는데, 아니 이건 무슨 일이야? 얼마전에 적은 주석에 대한 글답변과도 같은 글이 올라와 있는 것이다.

 

내용은 Flex Builder, Flash Builder에서도 TODO, FIXME를 쓸 수 있는 플러그인이 있다는 것.

 

글은 Flex Builder 2 기준으로 쓰여있지만 Flash Builder에서도 된다.

 

1. Flex Builder 2 Task Plugin 1.0.0을 다운받고 압축을 푼다.

2. plugins 디렉토리를 Flash Builder plugins에 덮어씌운다.

3. Test.mxml 은 테스트 파일이니 필요없다.

4. Flash Builder 기준으로 다음을 실행한다.

 

메뉴 -> Window -> Other Views... -> General -> Tasks

2010년 1월 25일 월요일

주석 패턴

iPhone 개발을 위해 Xcode를 사용하던 무렵에는 이런 주석들을 많이 달았다.

 

// TODO:

// FIXME:

// ???:

// !!!:

 

개발툴인 Xcode에서 이렇게 달린 주석들은 따로 관리를 해주기 때문이다. 이클립스에서도 // TODO: 를 지원해주던 것으로 기억한다.

유닛테스트 코드 커버리지 수치 높이기

Coverage 20%에서 80% 올리기는 쉬웠는데 오늘 테스트 추가하고 전체 커버리지 확인하니까 83%다. ㅎ

2010년 1월 24일 일요일

혼자 일하면 준비해야 하는 것

1. FlexPMD

2. Flex Coverage

3. Flex mojos, maven, with hudson.

4. git

5. 연습장

6. -Bemga- 간식

7. 포맷, OS 자동 설치. 백업 & 리스토어 자동화.

 

트리 구조에서

트리 구조에서 고민이 생겼다.

 

 

 

1.

다음과 같은 구조를 만들었다.

(1)

H 밑에 Is,

Is 밑에 J,

J 밑에 Ks,

Ks 밑에 K

 

복수 데이타를 담고있는 콜렉션 층이 없어지면 좋지 않을까 생각했다. 다음처럼 생각했다.

(2)

H 밑에 I,

I 밑에 J,

J 밑에 K

 

그러나 생각해보니 (2) 구조를 사용하면 다음과 같은 상황에서 불편해진다.

(3)

A 밑에 Ks

 

(1)을 사용하면 Ks를 바로 사용하면 된다.

(2)의 경우 어떻게든 하려면 J를 써야하는데 J와 Ks의 의미가 다르다.

(3)의 경우가 생기지 않는다면 (2)가 더 좋을지 의문이 생기긴 하다.

 

 

 

2.

자식의 메소드를 대신 실행하는 헬퍼 메소드가 복잡해 보인다는 생각이 들어 고민을 했는데 이는 위 상황때문에 생기는 문제가 아니다. (2)의 경우라도 헬퍼 메소드를 넣으려면 필요하다.

tree.H
    .addI
    (
        I.createI().setID("1").setName("일")
    )
    .addI
    (
        I.createI().setID("1").setName("일")
    )

 

헬퍼 메소드는 별 것은 아니고 hibernate의 DML-style operations을 참고삼아 만든 것이다. add, get, remove 형태의 콜렉션 메소드들은 데이타를 생성하고 추가할 때 자식 오브젝트를 생성하고 추가를 해야한다. 코드 상에서 생각하면 추가 작업(add method)의 등장이 자식의 생성보다 늦게 나타난다. 복잡한 부모-자식 구조라면 코드를 읽는 시간을 늘린다(고 생각하는데 아닐 수도 있겠지만 나는 그렇다). 그래서 사용한 방법은 마지막으로 넣은 object가 자신을 return 하여 점(.)을 찍고 추가 연산을 가능하게 하는 방법이다. 이렇게 하면 부모가 더 위에 나타나고 자식은 밑에 나타난다. 들여쓰기까지 사용하면 더 구조적으로 보인다. 더러 쓰이는 방법으로 알고있다. 예전에 JAVA nio 쓸때도 이런 메소드들이 많았던 것으로 기억한다.

 

아무튼 이 방법은 어떤 컨텍스트에서 작업을 했느냐가 중요하다. 깊이 있는 자식 object를 다루다가 부모 오브젝트 쪽에서 추가 작업을 하고싶으면 다시 부모로 올라가는 쉬운 방법이 없어 보인다. 그래서 헬퍼 메소드는 트리 구조의 상단에서 편하게 메소드를 호출하는 구조도 있지만, DML-style operations 처럼(이 말을 써도 되는지 아직 잘 모르겠음)메소드 체이닝처럼 데이터를 생성해낼 때 return 타입을 달리 할 수 있어 편리하다.

 

 

 

3.

결론적으로 각 클래스는 자신이 어떤 위치에 속해있는지를 모르게 설계하는 편이 좋을 수 있다는 것.

2010년 1월 19일 화요일

FlexUnit 4 UI 테스트 방법

[Before(async, ui)]
public function setUp():void
{
 myView = new MyView();
 Async.proceedOnEvent(this, myView, FlexEvent.CREATION_COMPLETE);
 UIImpersonator.addChild(myView);
}
 
[After(async, ui)]
public function tearDown():void
{
 UIImpersonator.removeChild(myView);
 myView = null;
}

 

 

 

1. 위의 코드처럼 setUp과, tearDown을 구성한다.

2. UIImpersonator에 테스트 하려는 컴포넌트를 테스트 메소드 실행 전에 붙였다가 끝나고 지우는 구조.

 

 

 

[Test(async, ui, order=1)]
public function testDoWork():void
{
 Async.handleEvent(this,
  myView,
  MyView.WORK,
  onWorked,
  LONG_TIME);

 myView.doWork();
}

private function onWorked(event:Event, passThroughData:Object):void
{
 Assert.assertTrue(myView.isEverythingOkay());
}

 

 

 

3. 이벤트 등을 받아서 Assert 사용.

2010년 1월 15일 금요일

FlexUnit 4 비동기 테스트 방법

FlexUnit 4에서 비동기 테스트 방법

 

[Test(async, description="Async Example")]
public function testTimerLongWay():void
{
 var asyncHandler:Function = Async.asyncHandler(this, handleTimerComplete, 500, null, handleTimeout);
 timer.addEventListener(TimerEvent.TIMER_COMPLETE, asyncHandler, false, 0, true);
 timer.start();  
}

 

protected function handleTimerComplete(event:TimerEvent, passThroughData:Object):void
{

}

 

protected function handleTimeout(passThroughData:Object):void
{

}

 

1. Tag에 async를 준다.
2. Async.asyncHandler를 통해 비동기 핸들러를 만든다.
2.1. this - listener 클래스를 지정한다.
2.2. handleTimerComplete - timer에서 TIMER_COMPLETE 이벤트가 발생했을 때 처리 될 이벤트 핸들러.
2.3. 500 - 대기시간을 넣는다. 이 시간이 초과하면 handleTimerout 이벤트 핸들러가 실행, 테스트는 실패.
2.4. null -  대신 어떤 값을 넣으면 handlerTimerComplete의 두 번째 인자로 넘어온다.
2.5. handleTimeout - 앞서 설명한 것처럼 테스트 타임아웃 시에 호출되는 펑션.
3. timer.addEventListener에서 Async.asyncHandler를 통해 생성한 핸들러를 넣는다.

 

위처럼 하면 된다.

 

위의 예에서 이벤트가 발생하면 handleTimerComplete가 호출되고

 

Assert를 사용하여 테스트를 시작하면 된다.

2010년 1월 3일 일요일

YUI PHP Loader 문제

YUI PHP Loader를 사용하여 YUI를 로드하면 w3c html validator 에서 문제가 생긴다. 내가 이상하게 사용 한 것인지 모르겠지만 아직은 못쓰겠다.

YUI2 Carousel 적용시 주의사항

YUI 2의 Carousel 컴포넌트의 예제 Using both images and text within an item(아이템 하나에 이미지와 텍스트 같이 사용하기)를 사용하려고 했다.

 

YUI 2 로더에서 "animation", "carousel" 두 개를 load하고 몇 가지 보이는 class를 로드하였으나 위쪽 페이저 부분이 이상하게 나왔다.

 

결국 코드를 한 줄, 한 줄 비교해본 결과 body tag가 문제였다. body 태그를 다음처럼 해줘야 Carousel 컴포넌트가 제대로 출력된다.

 

<body class="yui-skin-sam">

...

2010년 1월 2일 토요일

YUI 3 Basic Left Nav 예제 사용시 주의사항

YUI 3 Basic Left Nav 예제를 사용해서 메뉴를 만드려고 했다. 쉽게 쉽게 되는가 싶었는데 yahoo의 example은 메뉴가 깔끔하게 나오는 반면 내 서버에서 돌린 코드는 메뉴가 펼쳐졌다 접히는 과정이 다 보여졌다.

 

소스코드는 완전히 똑같은데도 그래서 계속 찾아보니 html 코드 중에 이런 부분이 있었다.

 

<link rel="stylesheet" type="text/css" href="assets/node-menunav-examples-base.css">

 

내 서버에는 없는 파일이라 관련 스타일이 적용되지 못했던 것이다. 따라서 바로 아래 나타나는 다음 코드가 작동을 못했다.

 

<script type="text/javascript">
        // Hide the menu while its dependencies are being loaded
        document.documentElement.className = "yui-loading";
</script>

 

"yui-loading" 은 메뉴를 감추는 작업을 한다. 로딩하는 동안 메뉴를 감춰서 메뉴가 그려지는 과정을 감춰 보기좋게 한다.

 

메뉴가 다 로딩되면 그려주게 된다.

 

menu.get("ownerDocument").get("documentElement").removeClass("yui-loading");

 

또한 메뉴의 id를 productsandservices로 해주지 않으면 css가 적용되지 않을 수 있으므로 sample을 참고할 때 주의해야 한다.

YUI2 VS YUI3

YUI3을 쓰기엔 YUI2의 위젯들이 탐났다. 그래서 YUI3을 포기하고 YUI2를 쓰는 사람이 있나 찾아봤더니 섞어쓰면 되는 거였다. ㅎ

 

http://yuilibrary.com/forum/viewtopic.php?p=3531

 

YUI 2.x와 3.x를 섞어쓰는 예제도 있다.

 

http://developer.yahoo.com/yui/3/examples/yui/yui-compat.html

 

앞의 포스트에서 서버사이드에서 YUI를 로딩 해주는 로더 설명을 썼는데 여기서도 Loader instance 두 개 만들어서 2.x, 3.x 동시에 load하면 된다.

PHP에서 YUI 삽입하기

YUI야 Javascript 라이브러리인데 PHP가 무슨 상관일까?

 

 YUI PHP Loader라는 Utility가 있다.

 

이 유틸리티는 YUI 컴포넌트를 로딩해주는 역할을 한다.

 

클라이언트 사이드에 YUI Loader가 있다면 php 서버사이드엔 YUI PHP Loader가 있다.

 

php 쓰는 김에 같이 쓰기로 결정.

 

php에서 제공된 loader.php를 include 하고 아래와 같이 코드를 실행하면 된다.

 

$loader = new YAHOO_util_Loader("2.8.0r4");
$loader->load("yahoo", "dom", "event", "tabview", "grids", "fonts", "reset");

 

3.0이 좋다하여 $loader = new YAHOO_util_Loader("3.0.0"); 으로 바꿨더니 잘 되는 것같다.

 

서비스 서버에 올릴때 meta 디렉토리가 담겨있는 lib 디렉토리를 빼먹으면 안된다.

2010년 1월 1일 금요일

바쁜 마음

가끔 나만 알아볼 글쓰는 게 싫을때가 있다. 마음이 바쁘다. 어떻게든 되겠지. ㅎ

한 일과 할 일

구조개선

Flash와 PHP 통신에서 서버사이드는 필요한 데이터를 DB에 쿼리하고 XML로 만들어서 던져주는 작업을 했다. output인 xml은 달력 전체를 표현하는 xml과 한 개의 달력을 표현하는 xml이 주를 이루고 있는데 이 부분이 너무 DB에만 의존적이어서 클래스로 만들었다. 유닛테스터가 매우 큰 도움이 됐다. 이제 테스트 어디에서 에러가 나는지 보고 어떤 코드가 문제인지 바로 알 수 있게 됐다.

 

XML

위에서 말한 객체들이 XML을 알아서 만들기 때문에 통합 XML의 경우 객체간의 통신이 중요했다. 따라서 XMLWriter의 개선이 필요했기에 php에서 제공하는 xml 기술들을 찾아보는 시간이 있었다. 간단한 작업이기에 XMLWriter를 사용하기로 했는데 내가 갖고있는 두 개의 호스팅 서비스 중 한쪽에서는 XMLWriter를 지원하지 않는다. 속도 체크를 해봤는데 스트링으로 XML을 만들어내는 것보다 XMLWriter가 아주 약간 더 빠르다. 어느 서비스에서 어떤 알고리즘을 사용할지 쉽게 결정할 수 있게하고 다양한 알고리즘을 같은 구조로 지원할 수 있게 하기위해 인터페이스로 뺐다. 이제는 시스템 전반적으로 호스팅 환경 설정에 따라 알맞는 XMLWriter를 생성해준다.

 

XML 구조

XML 구조가 클라이언트 호출 정보에 대한 요약을 담고 있었는데 불필요했다. 실제 필요한 데이터만 갖고 있으면 됐기에 전반적인 정보를 담기위해 여기저기에 XML을 던지던 구조를 던지는 타이밍에 XML을 생성하는 구조로 바꿨다. 따라서 output이 XML이 아니더라도 더 적용하기 쉽게 됐다.

 

로깅

SQL 인젝션 예방차원에서 모든 쿼리에 대한 로깅을 했었는데 아무래도 닭질같아 input 체크를 심하게 해놨으니 input을 벗어난 시도를 한 경우와 실패한 경우에 대해서 로깅을 하게 해놨다.

 

버전관리

버전관리를 하여 개발과 배포를 동시에 진행할 수 있도록 했다. 혼란을 피하기 위해 클라이언트에서 현재 접근하고 있는 서버의 위치나 버전정보등을 볼 수 있게 했다.

 

달력

스스로 작심을 쓰기위해 달력을 새로 만들었다.

 

--

 

할 일

클라이언트 환경에서 예외가 생기는 경우 플래시 영역에 이 정보를 저장하고 다시 전송 할 수 있을때 예외 정보를 전송할 수 있게 했으면 한다.

 

아직 텍스트 리소스가 얼마 없을때 다국어 지원을 미리 해두는 것이 좋을 것이라 생각한다.

 

속도 테스트하기 전에 테스트 할 메소드를 여러번 호출해줘야 속도가 제대로 나오는 것같다. 안그러면 무조건 제일 처음 호출된 메소드가 항상 느리다. 알아보자.

 

JAVA의 import 같은 형태를 지원하게 해봐야겠다. 패키지 구조로 나누는 게 편하다.

 

작심 HTML 버전을 만들면서 테스트를 강화하고 yui를 공부한다.

 

DB가 mysql 함수를 쓰다보니 close 하면 모두 다 close 돼버리고 그런다. stack 구조로 해제하게 한다.

2010년

2010년 새해다. 2010년, 뭔가 익숙하다는 생각이 계속 들었다. 2010 원더키디. 아뿔싸 벌써.