페이지

2013년 1월 20일 일요일

scot anderson, 최고의 아빠(dad)


아이를 키우다보면 참 어렵다고 느낄때가 많다. 어떻게 해야 좋은 아빠가 되는것인지, 좀 더 친해지려면 어떻게 해야하는지 자신감을 키워주고 싶을때 어떻게 해야하는지..
요즘 아들과 티격태격하는 나를 보더니 와이프가 빌려온 책이다. 내용도 좋고,  번역의 질도 좋다. 아마존에서 찾아보니 dad란 제목으로 parenting 부분에서 베스트셀러였다. 역시나 라고 생각했다.
약간 의외였던 것은 저자는 엄마가 집에서 아이들을 돌봐야 한다고 생각하는 것이였다. 우리의 생각과 다르지 않은 이유에서. 할머니와 베이비시터가 엄마 같은 사랑을 줄 수 있을까 생각해보면 나도 그 의견과 다르지 않다. 하지만 와이프의 커리어가 단절되는 부작용도 무시할 수 없다. 어려운 문제다.

이 책을 감히 요약해보면 이렇게 된다.

먼저 훌륭한 아빠가 되겠다는 비전을 세워야 한다. 사람은 비전이 없으면 스스로를 억제하지 못하기 때문이다.(p21)
아이들과 시간이 아닌 관계를 쌓고(양보다 질), 그 관계를 위해선 신뢰라는 기초공사를 단단히 해야 한다.(p56)
그 신뢰를 얻기위해 가장먼저 할 것은 아내를 사랑하는 일이다. 아이들의 인생에서 가장 중요한 엄마를 사랑하지 않는 아빠를 아이들이 어떻게 신뢰할 수 있을까. 훌륭한 남편 다음이 훌륭한 아빠의 자격이 있다. (p72)
아내의 사랑을 얻기위한 방법들:
. 퇴근해 집에 온후 15분은 아내를 위한 시간으로 할애하라
. 아내의 필요를 충족하라(아이와 함께 엄마의 선물을 준비)
. 이혼을 입에 올리지 말고
. 아내와 정기적으로 데이트 하고
. 사랑한다고 소리내어 말하고
. 애정을 표시하고
. 아내와 한편이 되어라

가족과 좋은 추억을 쌓아라.
명심하라. 인생이란 추억거리를 만다는 과정이다. 가족의 추억을 만드는 것은 아빠의 책임이다. 어릴때 다양한 추억을 만들어주고 함께 시간을 보낸다면, 아이들은 커서도 당신과 계속해서 추억이 될 시간을 함께 부내고 싶어할 것이다. 가족에게 멋진추억을 심어주지 않았으니 멋진 추억을 수확한다는 것은 당연히 불가능하다.(p126)
. 아이들이 어릴때부터 당신과 함께 보내는 시간을 소중하게 여긴다면, 당신이 나이가 들었을때 그들도 당신과 보내는 시간을 소중히 여길 것이다.(p134)

아이들과의 약속은 꼭 지켜야 한다. 신뢰의 문제이므로..
약속을 할때는 지킬 수 있다는 확신이 있을때에만 하라(p168)


아들의 사랑의 언어를 파악하고 그 언어로 사랑을 말하자. (사람마다 사랑을 표현하는 방식과 느끼는 방식이 다르다)
5가지 사랑의 언어
. 선물
. 도움
. 함께 보내는 시간
. 격려
. 애정표현

듣기는 속히 하고 말하기와 성내기는 더디하라(p215)

말다툼에서 이기는 유일한 방법은 말다툼을 피하는 것이다.(p225) 왜냐하면 상대방의 의견이 틀렸다는 것을 설득했다 하더라도 그의 의견은 변하지 않기 때문이다. (p226)


격려와 칭찬을 통해 아이의 자존감을 키워줘야 한다. 능력이 있든 없든 매력이 있든 없든 계속해서 우리에게 좋은 말들을 해주는 머릿속 녹음기를 우리는 자존감이라고 부른다.(p257)

예를 들면 이렇게 말해주며 같이 꾸준히 야구 연습을 해준다. 그러다 보면 진짜 실력이 좋아질 것이고.. 뭐든 노력하면 이렇게 할 수 있구나 란 것을 느끼게 해주면 된다.
- 야구못하겠어요.
+ 아들아 너는 아주 잘하고 있어. 넌 뭐든 노력하면 잘하잖니? 이번주에 조금만 더 연습하면 돼. 방금전에 네가 잡아냈던 공 기억하지? 정말 대단했어
- 하지만 아빠. 난 매번 삼진아웃 당하는 걸요.
+ 아들아, 지난 번에 아빠랑 같이 봤던 야구 경기 기억나? 세계 최고의 타자인 새미소사도 삼진아웃 당했잖니(p260)
. 내가 내 자신을 어떻게 보느냐에 따라서 세상이 나를 어떻게 보느냐가 결정된다. (p266)

낳아준 아빠 -> 부양하고 보살피는 아빠 -> 관계를 쌓는 아빠 로 진화해 가야 한다(283)


아이들은 자기행동의 결과를 예상할수 있을때 훨씬 안정적이고 행복하게 지낼수 있다. 그러므
로 훈육에 일관성이 있어야 한다. (p312)

아이가 무언가 실수를 했을때는 이런 패턴으로 말을 하자.
유리잔에 우유가 들어있을때는 조심해서 행동해야지. 자 흘린 우유는 네가 치우렴. 유리잔에 든 우유를 네 스스로 책임지지 못한다면 할 수 있을때까지 빨대를 사용할 거야(332)

통계적으로 책을 처음 한번 읽으면 전체 내용의 20파센트만 기억한다고 한다.(348) 그러니 이책을 몇번 더 읽으라

2013년 1월 19일 토요일

git

내가 여지껏 써본 revison control software(RCS) 는 소시적 MS SourceSafe , Rational ClearCase, Perforce, Git 등이 있다.

Clearse에서 Peforce로 처음 바꿨을때 그 속도에 감탄했었다.  Peforce가 빨랐다기 보다는 ClearCase가 너무나 느렸던 탓이다. 실제로 Perforce와 SVN의 속도를 비교해보면 p4가 더 빠르긴 하지만 큰 차이는 없는 것으로 알고 있다.

git을 반년정도 써오고 있는데 지금까지는 아주 basic한 workflow만 써오다가, 복수개의 remote 서버를 추가해서 로컬 브랜치로 만들고 각 브랜치 간의 머지 및 integration을 로컬에서 할 수 있음을 알고는 git의 강력함을 느꼈다.

시나리오를 만들어 보면

  • git remote 서버들
    • team의 master 서버인 origin
    • 오픈소스여서 대외적으로 공개될 git인 rsa
  • 로컬 브랜치들
    • develop : origin/develop
    • release : origin/release
    • rsa : rsa/master
  • workflows
    • dev 에 비교적 unstable한 코드들을 넣고  커미하고 자가 검증
    • integration을 하기 위해 최신 develop 브랜치 로 release로 overwrite하고 integration build를 만들어서 검증팀에 주고 디펙 수정
    • 각 마일스톤 별로 release criteria를 만족하면 rsa로 push
    • rsa에서 디펙 어싸인이 되면 rsa브랜치에 quick fix를 하고 develop 브랜치에 머지
    • release 디펙 어싸인되면 release브랜치에 quick fix를 하고 develop에 머지
위 workflow를 git이 아닌 p4로 한다고 생각하면 일이 생각보다 복잡해진다.
  1. 우선 develop/ release, rsa의 working copy를 만들어야 한다. 대부분의 코드는 같을 것이기 때문에 여기서 많은 하드 공간이 낭비된다. git은 같은 hash를 가지면 그것을 브랜치 간에 share하기 때문에 엄청난 효율을 가질 수 있다. perforce도 서버단에서는 같은 오브젝트임을 알지만 로컬에  N번의 working copy를 sync해야 하는 것은 어쩔 수 없는 비효율
  2. 1에서 만약 rsa가 물리적으로 다른 서버라면 서버단에서도 같은 오브젝트가 아닌 다른 오브젝트로 인식할 것이므로 또 비효율이 발생할 수 있다.
위 시나리오에서 브랜치가 더 늘어나고 remote더 늘어날 수록 개발자가 감당해야 하는 복잡함은 perforce쪽이 더 많아 진다. peforce 대신에 Centralized RCS 로 단어를 바꿔도 같은 뜻이 된다. 즉, Centralized계열의 한계라고 볼 수 있다.

게다가 훌륭한 code review툴인 gerrit까지 무료로 쓸 수 있지 않은가
RCS가 git으로 천하통일 될 수 밖에 없는 이유 되겠다.






2013년 1월 15일 화요일

돈으로 의지를 살 수 있는가

요즘 레슨을 받으며 느끼는 것이 있다.

레슨을 받으면
불과 이십분만에 땀을 뻘뻘 흘리고 숨이 차다.
근데 이것을 혼자서 이렇게 해보려고 하면 절대 이런강도가 나오지 않는다.
너무 힘들면 그만해 버리기 때문이다.

PT도 마찬가지
PT할때는 운동도 잘되고 근육붙는게 눈에 보인다.
하지만 PT가 끝나고 혼자 헬스장을 다녀보면
그 근육들은 금방 풀어져 버린다.
한번씩 빠지기도 하고
음식 조절에도 실패하기 때문에

돈을 내고 레슨/PT을 받으면
내가 지불한 돈의 가치때문에
빠뜨리지 않고 하게 되고
강사가 극한으로 잘 이끌어 준다.

이는
돈으로 강사의 시간을 사서 나의 시간을 save하는 것이며
한편으로는
나약한 의지를 돈으로 사는 것이다.

매일 운동 하는게 힘들다면
적지않은 돈을 지불하고 운동을 해보자
의지가 충만해질테니까



2012년 12월 13일 목요일

Manipulating Texts in Eclipse

Manipulating texts in Eclipse

History

revisionchangesauthor
0.1initial version 2012-12-05 수 Darren Ha
0.2textBuffer.commit 2012-12-13 목 Darren Ha

Introduction

manipulating texts in Eclipse way can be hard for initial Eclipse plugin developers. I couldn't find any structured tutorial or articles. So this articles is born. any comments about the contets are welcomed! I hope it helps you too.

Getting IDocument form a IPath

A FileBuffer represents a file that is being modified over time. Fille buffers for text files provide IDocument(a content model) and IAnnotationModel(a marker model). so IDdocument is essential for manipulating texts.
ITextFileBufferManager bufferManager = FileBuffers.getTextFileBufferManager();
IPath path = new Path("/sample/test.h");
try{
    bufferManager.connect(path, LocationKind.IFILE, monitor);
    ITextFileBuffer textBuffer = bufferManager.getTextFileBuffer(path, LocationKind.IFILE);
    IDocument document = textBuffer.getDocument();
}finally{
    bufferManager.disconnect(path, LocationKind.IFILE, monitor);
}  

Creating and applying TextEdit

We can modify IDocument using TextEdit subclasses: e.g. ReplaceEdit, InsertEdit, DeleteEdit to apply those changed multiple times in a file, you should use MultiTextEdit which is tree container of TextEdits. MultiTextEdit::apply can produce an error if the changes made at the same location at multiple times.
MultiTextEdit::apply doesn't change file contetns immediately. to change file content you must call ITextFileBuffer::commit.
ITextFileBuffer textBuffer = ...;
IDocument document = ..;

FindReplaceDocumentAdapter finder = new FindReplaceDocumentAdapter(document);
IRegion regionReplace = finder.find(0, "textTobeReplaced", true, true, false, false);
IRegion regionInsert = finder.find(0, "//TODO", true, true, false, false);

MultiTextEdit multiEdit = new MultiTextEdit();
multiEdit.addChild( new ReplaceEdit(regionReplace.getOffset(), regionReplace.getLength(), "ReplacedText"));
multiEdit.addChild( new InsertEdit(regionInsert.getOffset(), regionInsert.getLength()));
multiEdit.apply(document);
textBuffer.commit(monitor, true);

using CDT refactoring mechanism

You can use CDT built-in refactoring framework to change texts more elegant way. the following codes demonstrate invoking rename refactoring of CDT programtically. You can invoke this by clicking Alt+Shift+R in eclipse source editor. It's cool!
If the indexer has unresolved symbols , when build is broken, the refactoring operation can fail.
IFile file = new File("/sample/test.h");
IRegion region = ...;
CRefactoringArgument arg = new CRefactoringArgument(file, region.getOffset(), region.getLength());
CRenameProcessor proc = new CRenameProcessor(CRefactory.getInstance(), arg);
proc.setReplacementText("ReplacedText");
proc.setSelectedOptions(-1);
proc.setScope(TextSearchWrapper.SCOPE_SINGLE_PROJECT);
CRenameRefactoring refactor = new CRenameRefactoring(proc);

((CRenameProcessor)refactor.getProcessor()) .lockIndex();
try{
    RefactoringStatus rs = refactor.checkInitialConditions(monitor);
    if (rs.hasFatalError()) {
        throw new Exception("checkInitialcondtion fail");
    }
    rs = refactor.checkFinalConditions(monitor);
    if (rs.hasError()) {
        throw new Exception("checkFinalcondtion fail");
    }
    Change change = refactor.createChange(monitor);
    change.perform(monitor);
}finally{
    ((CRenameProcessor)refactor.getProcessor()).unlockIndex();
}

2012년 12월 4일 화요일

자신부터 믿어야 한다.

가끔 자신이 믿지 못하는 것을
타인에게 믿으라며
말을 하는 경우가 있다.

면접을 볼때
난 이런 이유로 지원했고 그것은 이렇게 되어야 한다고 생각한다.
고 말했으나 정작 내 머리속에선 물음표가 그려질때

동료에게 그럴땐 이렇게 하라고 조언하지만
정작 내가 그렇게 해본적이 없어
물음표가 그려질때

자기자신도 믿지 못하는 말을 할땐
어떻게든 티가 나기 마련이다.
자신도 납득시키지 못한 말 혹은 논리로
어떻게 다른 사람을 납득시킬 수 있겠는가.
면접에서든 세미나에서든 동료와의 대화에서든..

허경영이란 사람.
사이코 혹은 이상한 사람으로 불릴지라도
적어도 그는 자기 자신을 확실히 믿고 있다.
믿지않으면 그런 포스는 나오지 않는다.

자기를 설득하지 못한 그 무엇을
입밖으로 내지말자. 그 말은 공허할 뿐이다.
허경영보다 못한 이가 되어서는 안되지 않겠나

2012년 11월 30일 금요일

손미나, 변신의 시작은 바로 나

어렴풋이 아나운서를 그만두고 여행을 다닌다고만 알고 있었는데 어느새 회사에 특강을 하러 왔다기에 냉큼 달려가 그녀를 보았다.
기억나는 꼭지들..

midnight in Paris 꼭 한번 봐라.
거기 나온 명대사.
자신의 현재에 만족하는 사람은 없다.

너 자신을 알라.
낯선곳 아무도 자기 자신을 알지 못하는 곳에 가봐야 진짜 내가 드러난다.
나의 경우는 스페인 어학 연수 시절에 나의 이런면을 알았다.
- 호기심이 많고
- 여러 사람과의 대화에서 리드하며 (하물며 말도 잘 안통함에도..)
- 사람이 많을수록 떨지않고
그래서 아나운서란 직업이 내게 맞을 것이라 생각해서 아나운서란 직업을 택했다.

슬라바 폴루닌의 snow show 기회가 되면 꼭 봐라
이 사람은 전직 엔지니어였고 마음속에 꿈틀대고 있는 그무엇을표현하기 위해 광대가 되고 싶어했으나 어머니가 반대했다. 아들의 요청으로 그의 5분짜리 공연을 보고 광대가 되는것을 허락했다고.



아르헨티나 빈민촌의 엑스트라 배우.
가난하다고 해서 꿈을 꾸면 안되나?
유난히 영화촬영이 많은 아르헨티나. 해서 엑스트라 모집에 신청서를 냄. 아무도 하지 않으려는 역할을 맡아서 인정받음. 그 후 많이 출연함.
그는 번 돈으로 빈민촌에 영화학교를 만들고 다수의 엑스트라를 배출 함. 국가도 하지 못한 변화로 빈민촌에 활기를.
태어나서 처음으로 쓸모가 있는 사람이라고 느껴져 너무 행복했다고 함.

내가 아나운서를 그만두고 여행을 간 것은 내가 한달만에 완성한 인생의 계획 중 하나였음.
1년은 과대평가 하고 일생은 과소평가 하는 우리
7-80살까지 보고 사는 사람은 조금 하지 않다.

중요한 갈림길에 섰을때 자신의 육감을 믿어라. 산악인들도 그렇게 한다고
아르헨티나 빈민촌에서 뒤에선 동네 깡패들이 따라오고
마침 택시가 지니가는데(택시를 타면 유괴를 많이 당함)
택시를 탈지 말지 고민하고 있으니 택시 기사가 당신이 왜 안타려고 하는지 않다.
내 눈을 봐라. 난 가족이 있고 먹여살려야 한다. 당신을 납치할 이유가 없다.
난 택시기사의 눈을 믿고 탔다. 무사했다.

프랑스에선 학교에서 등수가 없다고 한다. 놀라서 너넨 왜 등수가 없니? 라고 물으니
사람을 어떻게 등수를 매겨? 라고 한다.
등수를 매기면 하위는 좌절하고, 상위는 선두를 뺏길까봐 두려워 한다.
결국엔 평준화 되어 버린다.

프리랜서는 전혀 프리 하지 않다. 조금만 안주해도 금방 낙오되어 버리니까

인디언의 삶
1년이 13달이며
살아보고 결혼하고
사람이 죽었을때 파티를 열고
내가 내 노트북을 잃어버렸을때 인디언친구가 한말
미나, 원래부터 네 물건이었던 건 아무것도 없었어
그럼 내가 소중하게 찍은 이만장의 사진은 어떻할꺼야?
미나, 살아있음에 감사해야해. 사진은 다시 찍을 수 있잖아.

라틴국가는 우리나라와 비슷하게 한의 느낌을 안다.

박정자 선생님이 하시는 19 그리고 80 이란 연극 기회가 되면 꼭 봐라.
19세 소년과 80세 할머니의 연애사인데 보면 이해가 간다.
인생은 축구경기다. 90분을 힘껏 뛰지 않은 선수가 락커룸에서 고개를 들 수 있을까?

하루 5분 명상해봐 아침이 달라질 수 있다.

질답>
아르헨터나의 빈민촌은 위험했을 텐데 어떻게 갈 결심을 했나? 나로서도 내 책을 쓰기 위해서 리스크를 감수 한것.
앞으로의 계획? 프랑스 여행책을 낼것이다. 페루 마추피추에서 삶에 대해 다시 생각을.. 내가 성장하지 않은 상태에서 또 다른 여행책을 낸다는 것은 아무 의미가 없다고 생각했다.

2012년 11월 28일 수요일

Eclipse Wizard Tutorial

Wizard

History

revisionchangesauthor
0.1initial version 2012-11-28 수 Darren Ha

Wizard

Wizard 클래스에서 상속받아서 클래스를 만든다. IImportWizard interface를 implement하는 이유는 eclipse의 import 메뉴에 사용하기 위해서 이다. 내부 구현을 보면 IImportWizard, IExportWizard, INewWizard 모두 같은 interface이고 단지 이름만 다르다. 따라서, IImportWizard를 implement한 클래스도 new project 혹은 export wizard에서 사용될 수 있다.
public class MyWizard extends Wizard implements IImportWizard {
    @Override
    public void init(IWorkbench workbench, IStructuredSelection selection) {
    }

    @Override
    public void addPages() {
        MainPage main = new MainPage();
        addPage(main);
    }

    @Override
    public boolean performFinish() {
        // TODO Auto-generated method stub
        return false;
    }
}

Wizard Page

MyWizard::addPages에서 추가될 page는 WizardPage를 상속받아서 만들고, Dialog와 마찬가지로 createControl에서 dialog를 구성해주면 된다.
public class MainPage extends WizardPage {
    public MainPage() {
        super("main");
    }
    @Override
    public void createControl(Composite parent) {

        Label l = new Label(parent, SWT.NONE);
        l.setText("test");
        setControl(l);
    }
}  

Validating each page's input

WizardPage::setPageComplete()로 해당 페이지의 input이 조건에 맞게 들어왔는지 검사해서 next 버튼을 enable할지 여부를 판단한다. SetMessage 함수로 여러가지 메세지를 wizard 헤더 영역에 나타낼 수 있다. 아래는 Text control에 제대로 된 비밀번호를 입력했을때만 finish 버튼을 enable하는 부분임.
protected void updatePageComplete() {
       setMessage(null);
       setPageComplete(false);

       String pwd = fText.getText();

       if (!pwd.equals(PASSWORD)) {
           setMessage(MSG, ERROR);
           return;
       }

       setPageComplete(true);
   }

Launching Wizard

Wizard Extension Points

eclipse의 File>New/Import/Export에 나타나게 하려면 eclipse가 제공하는 wizard extension point를 추가해야 한다. Eclipse의 plugin.xml editor에서 extension tab으로 이동한 후 아래 extension중 하나를 추가. new project -> org.eclipse.ui.newWizards import -> org.eclipse.ui.importWizards export -> org.eclipse.ui.exportWizards 추가한 extension point의 하위에 context menu를 이용하여 wizard 를 추가. class 를 실제 구현한 클래스의 이름을 추가하여 매핑해준다.

Using WizardDialog

WizardDialog를 이용해서 언제든 Programatically wizard를 띄울 수 있다. 아래 처럼.
public Object execute(ExecutionEvent event) throws ExecutionException {
        IWorkbenchWindow window = HandlerUtil.getActiveWorkbenchWindowChecked(event);
        IStructuredSelection selection = StructuredSelection.EMPTY;

        ISelection sel = HandlerUtil.getCurrentSelection(event);
        if (sel instanceof IStructuredSelection) {
            selection = (IStructuredSelection)sel;
        }


        MyWizard wizard = new MyWizard();
        wizard.init(window.getWorkbench(), selection);

        WizardDialog dialog = new WizardDialog(window.getShell(), wizard);
        dialog.open();
        return null;
    }

Tutorial Project

https://github.com/nberserk/eclipsetutorials 에 가시면 위에서 언급된 소스가 모두 포함된 eclipse project가 있습니다.