제가 selection 관련 부분의 소스를 추적해 봤는데요... 블록

일단 지난번에 올려드린 소스가 포함된 아래의 소스를 보시면... 에디터가 로드될 때 ed_seting_head.php 67행(여기선 4행) 쯤에서 DocReload() 가 호출되고 edit.js 해당 부분의 소스를 따라가 보면 clearInterval로 setInterval 사용을 중지하고 나서 DocLoading() 함수를 호출하고 있습니다. DocLoading() 를 따라가 보면 new CSelection(); 란 selectionObj 가 만들어집니다.

다음 ed_seting_edit.php 파일이 로드가 되면서 iframe의 onbeforedeactivate='deactivate_handler()'  가 호출되고 밑에 edit.js 소스 41행을 보면 selectionObj.PutSelection(); 가 호출되면서 edit.js 6번 행의 this.PutSelection = put_selection; 이 부분이 실행이 됩니다.

이 로직을 잘 분석해 보면 뭔가 해결점이 보일 것 같은데 아직까지 아리까리 하네요. ^^;

1
2
3
4
5
6
7
//javascript 소스: ed_seting_head.php
<SCRIPT language="JavaScript">
  <!--
    DocReloadInterval = setInterval("DocReload()", 300);    
    imgViewReloadInterval = setInterval("imgViewReload()", 300);    
  //-->
</SCRIPT>
 

[ed_seting_edit.php]
1
2
3
4
5
6
7
8
9
10
<div id='edit_windowdiv' name='edit_windowdiv' style='width:100%;'>  
<table width='100%' height='100%' border='0' cellpadding='0' cellspacing='0' class='sw_bd_style_6' style='table-layout:fixed'>
<tr>
<td align='center'>
    <iframe id='memoi' name='memoi' style='width:100%; height:100%; display:none;' onbeforedeactivate='deactivate_handler()' scrolling='yes' frameborder='no' border='0' ALLOWTRANSPARENCY='true'></iframe>
    <textarea id='memo' name='memo' style='width:100%; height:100%; display:block;' class='sw_bd_style_7' onkeydown='return doTab(event,this);'><?if($mode=="modify"||($mode=="reply"&&!$c_no)){ echo "$memo"; } ?></textarea>
</td>
</tr>
</table>
</div>


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
// JavaScript Code: edit.js
function CSelection()
{
    this.m_selection = null;
    this.GetSelection = get_selection;
    this.PutSelection = put_selection;
}
 
function get_selection()
{
    if(this.m_selection != null)
    {
        if(this.m_selection.type != "Control")
        {
            /*var oRng1 = memoiW.document.selection.createRange();
            if(memoiW.document.body.createTextRange().inRange(oRng1) == true)
            {
                oRng1.select();
            }*/
            if(memoiW.document.body.createTextRange().inRange(this.m_selection) == true)
            {
                this.m_selection.select();
            }
        } else {
            this.m_selection.select();
        }
    }
}
 
function put_selection()
{
    if(typeof window.getSelection != "undefined"){
        this.m_selection = memoiW.window.getSelection();
        this.m_selection.type = typeof memoiW.document.getSelection;
    } else if(typeof document.selection != "Control"){
        this.m_selection = memoiW.document.selection.createRange();
        this.m_selection.type = memoiW.document.selection.type;
    }
}
 
function deactivate_handler()
{
    if(DocReadyState)
    {
        selectionObj.PutSelection();
    }
}
 
function DocReload()
{        
    memoiE = document.getElementById("memoi");
    memoiW = memoiE.contentWindow;
 
    if(memoiW.document.readyState == "complete")
    {
        clearInterval(DocReloadInterval);
        memoE = document.getElementById("memo");
        DocLoading();
    }
}
 
function DocLoading()
{
    DocReadyState = true;
 
    memoiW.document.designMode = "On";
    selectionObj = new CSelection();
 
    if(edit_tag_yn == "Y" && memoE.value && !memoE.value.match(/(<IMG |<\/A>|<\/P>|<BR>|<BR \/>|<\/TABLE>)/i))
    {
        edit_tag_yn = "N";
    }
 
    if(edit_tag_yn == "Y")
    {
        var doc = memoiW.document.open("text/html");
        doc.write(default_source + memo2memoi(memoE.value));
        doc.close();
    }
    else
    {
        memoiE.style.display = "none";
        memoE.style.display = "block";
 
        if(edit_yn == "Y")
        {
            btnStyc();
            document.getElementById("htChk").checked = true;
        }
    }
    //memoiW.focus();
}
 



덧글

  • 2014/10/24 11:40 # 삭제 답글

    근데 진짜 궁금한게..xp에서 ie11 지원하나요?
  • 희망의빛™ 2014/10/24 16:46 #

    지원 안합니다. ^^; 익스8 까지만 지원될 거예요. IE11 테스트는 다른 곳 컴에서 테스트 했습니다. 저도 집에 있는 4대 컴은 다 XP 깔려 있어요. 굳이 업그레이드 하실 필요 없습니다.
  • 2014/10/25 20:51 # 삭제

    아니 내가 xp 쓰고있다는게 아니고 본인은 xp쓰면서 본인컴퓨터로는 테스트도 못할 ie11에 대한 지원을 왜 고민히고 있나 해서요
  • 2014/10/25 20:53 # 삭제

    덧붙여서 xp면 충분하다고 하면서 구버전 프로그램을 계속 붙들고 있는사람이 최신버전 프로그램에 대한 호환을 고민하는것도 좀 이상한것 같고..
  • 희망의빛™ 2014/10/25 21:54 #

    일단 다른 곳 컴에서 익스11로 접속했을 때 게시판이 제대로 동작을 안하니까 당연히 신경이 쓰일수 밖에요. 사람들이 윈도우7과 IE11을 쓰고 있다는 생각을 하니 호환성 문제를 해결해야겠다는 생각이 들었습니다. 그래서 이번에 고민을 하게 되었습니다. 물론 전 이것이 본디 불필요한 작업이다라고 생각을 하고 있습니다만... 만약 이렇게 잘 동작하던 게시판이 브라우저 업그레이드로 동작하지 않는다라고 한다면 아무리 누군가 심혈을 기울여 제작한 게시판이라고 하더라도 제작자가 죽고 몇 년이 지나면 아마 그 게시판 소스는 아무 쓸모도 없는 퇴물이 되고 말 겁니다. 이 얼마나 슬픈 일입니까? 그래서 전 MS를 경멸하고 있는 것입니다. 답변이 되었는지...

    그리고 이런 관행은 신기술 도입이란 명분으로 개발자의 노력을 하루아침에 물거품으로 만드는 못된 관행이라고 봐도 무방합니다. 너무나도 소모적인 관행이라는 거죠. 소스를 언제까지나 재활용할 생각을 해야지 이런 식의 신기술 도입 방식은 절대 아니라고 봅니다. 제가 불만을 가지는 부분도 그런 부분입니다.
  • Miyun_86 2014/10/25 21:54 # 삭제

    애시당초 호환성 생각해보긴 했습니까? 생각했으면 이렇게 붙잡고 살리가 없겠기에 무의미한 질문이겠지만요...
  • 총통 R 레이퍼 2014/10/25 22:16 #

    그 재활용이 이제 털릴만큼 계속 털리니까 안털리게 하려고 새로운 기술을 도입하고
    그 재활용으로 시대의 요구를 충족시킬 수 없으니까 새로운 기술을 도입하는거 아니냐?

    구형 좌물쇠가 핀 몇개로 뚤리니까 신형 좌물쇠를 만들고 번호락을 만들고 전자록을 만드는데
    전자록에 구형 열쇠를 못쓰니까 뚤리든 말든 구형 좌물쇠를 계속 써야한다는 주장도 아니곸ㅋㅋㅋㅋㅋㅋㅋㅋ

    열쇠장인과 도둑의 관계라는게 뭔 소린지는 알기는 하냐?

  • 희망의빛™ 2014/10/25 22:23 #

    제가 수정한 부분이 어떤 보안상 문제점이 있는지 그걸 좀 설명해 주시죠. 예전에 크롬이 변경한 호환성 부분까지 아울러 설명해 주시면 고맙겠습니니다. 제가 링크해 드리겠습니다. http://bitly.com/Ipp26X

  • 총통 R 레이퍼 2014/10/26 00:29 #

    ㅋㅋㅋㅋ뇌는 장식인가 사람 말하는 것도 못알아처먹넼ㅋㅋㅋㅋㅋㅋㅋ
    이해가 안되지? 대가리가 딸리면 그런거란다.

    그리고 이런 관행은 신기술 도입이란 명분으로 개발자의 노력을 하루아침에 물거품으로 만드는 못된 관행이라고 봐도 무방합니다. <- 니가 한 병신같은 헛소리

    윈도우를 만드는 사람들은 개발자가 아닌가봐? 그 사람들도 개발자고 매일매일터지는 해킹이나 버그를 열심히 고치면서 노력하고 노력해 해킹 안당하고 버그 없는 새로운 기술을 만들어냈지.
    즉 윈도우를 만든 MS는 열쇠장인이야. 도둑놈이 모르는 새로운 기술로 자물쇠를 만드는 사람이지. 거기다 더 사용하기 쉽고 편리한 자물쇠를 만들면 금상첨화!

    근데 너님은 지금 새로나온 자물쇠에 니가 가지고 있던 열쇠가 안들어간다고 새로운 자물쇠를 만든 [개발자]를 널 괴롭히는 나쁜놈 취급하고 있고
    핀 하나로 열리던 구식 자물쇠에 열쇠구멍 하나 더 만들어 놓고는
    '열쇠구멍이 2개니까 안전함! 열쇠구멍을 3개 4개로 만들면 더 안전할꺼임!'
    이런 헛소리를 하고 있다는거지. 핀 하나로 열리는 열쇠구멍이 100개가 있어봐야 시간만 더 걸리고 어차피 열리거든?

    니가 개발자라면 MS까면 안되. 그 사람들도 개발자다 등신아. 시대에 못따라가는 개발자는 빨리 접고 딴 일을 해야하는거다. 어디 아는것도 배운것도 없는 무식하기 짝이 없는 호로새끼가 사람말을 하고 앉아있는지 신기하다.





    그리고 넌 이 글도 이해를 못해서 또 동문서답이나 하고 자빠지겠지.
  • 희망의빛™ 2014/10/26 06:58 #

    그러니까 제가 지금까지 호환성 변경했던 부분이 어떤 보안 문제를 야기하는지 그걸 구체적으로 말씀해보시라구요. 디게 말 못 알아듣네. 장황하게 사람 인식 공격하면서 뜬구름 잡듯이 얘기하지 말고... 꼭 제가 호환성 변경한 부분이 보안상 어떻게 위험하고 그걸 어떻게 개선했는지 그걸 설명해야 합니다. 해킹 방법도 설명해 주시구요. 그러기 전까진 당신은 그 잘난 욕설로 사람 해치려 하는 나쁜 사람 뿐인 걸로 전 판단하겠습니다. 알겠소?
  • 총통 R 레이퍼 2014/10/26 13:03 #

    http://blrun.egloos.com/category/%EC%98%A4%ED%94%88%EC%86%8C%EC%8A%A4
    너님의 문제점

    http://www.xpressengine.com/
    현존기술

    이정도까지 말해줘도 모르면 대화할 가치도 없겠지. 뇌가 없는거나 마찬가지니까

    애시당초 신기술 도입이 소모적인 관행이라는 이유가 '니가 배우려니 귀찮아서'인데 뭘 바라겠냐만ㅋㅋㅋㅋㅋㅋ
  • Hide_D 2014/10/24 12:53 # 답글

    친절하게 답이나 달아드리니, 잘 찾아보세요. 링크가 이상하게 걸리는데, .aspx까지 드래그하셔야 보입니다.

    (1) TextRange의 inRange 정보입니다. 인자 타입을 확인하세요. http://msdn.microsoft.com/en-us/library/ie/ms536450(v=vs.85).aspx
    (2) window.getSelection의 실행 방식입니다. 반환 타입 HTMLSelection을 확인하세요. http://msdn.microsoft.com/en-us/library/ie/ff975169(v=vs.85).aspx

    물론 그 이전에 http://help.dottoro.com/ljrfsgii.php inRange는 인터넷 익스플로러에서만 동작하는 녀석이고,
    this.m_selection.type != "Control" 이 IE를 구분하는 코드라고 생각해보면, 어디서부터 잘못되었는지 답이 나오죠.
  • 글리 2014/10/24 13:08 #

    레퍼런스는 http://msdn.microsoft.com/en-us/library/ie/ms536450.aspx 하고 http://msdn.microsoft.com/en-us/library/ie/ff975169.aspx 이렇게 링크거시면 되죠. IE11 변경점은 http://msdn.microsoft.com/en-us/library/ie/bg182625.aspx 몰래 패치도 아니고 공식적으로 당당하게 doucument.selection 대체한다고 적혀 있는데 뭔 깡인지...
  • Hide_D 2014/10/24 13:06 # 답글

    다시 코드를 봤더니, 엉망 진창이네요??? 이게 어떻게 돌아가죠? 왜 돌아가는거죠?
    이 코드가 정말로 IE8에서는 동작하는게 맞아요?
    애초에 동작할리가 없는 코드입니다.
  • 글리 2014/10/24 15:01 #

    var o = document.getElementById("memoi")
    var oRng1 = document.selection.createRange()
    var oRng2 = o.createTextRange().inRange(oRng1)

    백문이 불여일견이라 자기 입맛에 맞는 행동만 적어서 도대체 저 분 뭘 말하는지 이해가 안되지만, 어찌되었든 결론인 "된다"는게 참이면 이렇게 맞물려서 돌아갔겠죠. 저도 놓친게 있는지 모르겠지만 그렇다면 IE8에서 실행은 될겁니다.(물론 이게 다른 브라우저에서 무조건 된다는 소리가 아닌건 한분빼고 다 수긍할 수 있는 문제)
  • 희망의빛™ 2014/10/24 20:10 #

    ㅋㅋ 현재도 IE8과 크롬 파폭에서 잘 됩니다. 물론 크롬과 파폭에선 아이콘 비활성화 등 일부 기능이 동작하질 않습니다만... 깨알같은 영문 들여다 보려니 문서 해석하기도 힘드네요. 이 문서를 다 읽고서 소스 고쳐야 하는 현실이 정말 싫네요. MS가 자꾸 원망스러워집니다. 예전부터 전 계속 MS가 맘에 들지 않았지만 말입니다. 그리고 <!DOCTYPE> 이 얘기가 나오는데 이거 붙이면 제대로 동작하나요? 다른 브라우저별 호환성 얘기는 눈에 잘 들어오지도 않고... 방법이 있다고 한다면 정말 다행이지만 오늘은 컴을 많이 만져서 더 이상 코드 들여다 보기가 싫네요. 암튼 전 XP를 사용하는 관계로 어차피 테스트는 저희집에서 못하기 때문에 서두를 일은 아니네요.

    http://msdn.microsoft.com/en-us/library/ie/jj676915.aspx 이 문서도 있네요. "레거시 다큐먼트 모드 지정하기"

    IE11 호환성 맞추기가 쉽지 않습니다. 멀쩡하게 돌아가던 소스를 고쳐야 하는 관계로 제대로 적응하지 못하는 사이트들도 있을 것 같고... 한마디로 개발자들 힘들게 하고 열심히 개발해 놓은 사이트들 물먹이는 엿같은 상황이 아닐지... 업그레이드를 그래서 제가 싫어합니다. 자꾸 업그레이드 해봐야 달라지는 건 이런 것들 뿐이고 점점 느려지니까요.
  • 글리 2014/10/24 21:35 #

    와 이게 ㅋㅋ거릴 문제인가????? 이거 무슨의미지? 설마 비웃는건가? 이보세요. 여전히 호환성 설정을 모른다고 자랑 아닌 자랑을 하는거보니 호환성 선언이나 설정이 잘못되어 있는 상태라면 iframe에서 정보를 못가져올 가능성을 비롯하여 관련 문제가 있을 가능성이 여전히 남아 있는데???!? 설마 우선해서 검토해보자는게 다른거니 나머지 문제가 자동으로 기각되는 상황인줄 아는건가?? 그런거 아니에요. 정말 절레절레합니다. ㅡ_ㅡ
  • 희망의빛™ 2014/10/24 22:01 #

    꼭 한번 고쳐 보겠습니다. 비웃는 건 절대 아닙니다. ^^; 월요일날 테스트할 거 같애요. 시간이나 날라나 모르겠네요 그때. 저도 비슷하게 고쳐 본 기억이 있어서... 암튼 신경써 주셔서 감사합니다.
  • 희망의빛™ 2014/10/25 06:34 #

    근데 this.m_selection.select(); 이건 어떻게 처리해야 하는 건가요? 이 부분이 중요한데 거기에 대한 코드는 없네요. 지금 한번 적용해 보고 IE8에서 테스트 하려고 했는데 이 부분이 걸리네요.
  • 희망의빛™ 2014/10/25 07:55 #

    var o = document.getElementById("memoi")
    var oRng1 = document.selection.createRange()
    if(o.createTextRange().inRange(oRng1) == true)
    {
    oRng1.select();
    }

    =======================================================

    var o = document.getElementById("memoi")
    var oRng1 = document.selection.createRange()
    if(o.createTextRange().inRange(oRng1) == true)
    {
    memoiW.window.getSelection();
    }
    =======================================================

    var o = document.getElementById("memoi")
    var oRng1 = document.selection.createRange()
    if(o.createTextRange().inRange(oRng1) == true)
    {
    o.window.getSelection();
    }
    =======================================================

    edit.js 20행 부터 23행 까지 이렇게 세 종류의 소스 적용해 봤는데 크롬에선 당연히 되고 IE8에선 툴바레이어가 클릭이 안되는데요? IE8에선 마치 IE11에서 반응하는 것과 똑같습니다. 원래 소스는 IE8에서도 동작하구요. 오류메시지를 보면 58번째(여기선 edit.js 20행) 줄에서 "개체가 이 속성 또는 메서드를 지원하지 않습니다" 이렇게 뜹니다. 물론 IE11에선 테스트하지 못했지만 IE8에서 이렇게 if 문 inRange 단계에서부터 막히니까 의미가 없죠.
  • 글리 2014/10/25 08:42 #

    createRange()의 반환 타입이 Range인데 뭔 재주로 이것만 가지고 select() 메소드가 작동한답니까? ㅋㅋ거리며 MSDN 레퍼런스 보시는거면 거기 적힌건 익스큐즈해야 되는거 아닙니까? 에러 뜨자마자 님 눈으로 확인하면 1분도 안걸리는거 저도 몇분을 허비하고 님은 몇백분을 허비하시네요.
  • 글리 2014/10/25 08:51 #

    한번 더 생각해보니 저기서 해매면 월요일에도 진도가 안나갈 가능성이 너무 높아보여 길잡이가 되 줄 솔루션은 던져주고 갑니다.

    if (document.selection.type != "Control") {
    // TextRange
    var textrange = document.selection.createRange();
    } else {
    // ControlRangeCollection
    var ctrlcollection = document.selection.createRange();
    }
  • 희망의빛™ 2014/10/25 17:13 #

    ㅋㅋ 이미 동작하는 부분을 건드린 소스를 가지고 길잡이라고 알려주시니 저로서도 황당하네요. this.m_selection.select() 이부분이 동작을 안한다니까요. inRange(this.m_selection) 이 부분도 동작을 안하구요. 물론 ie8과 크롬 파폭에선 제대로 관련 루틴이 동작합니다. 글리님이 제시한 코드를 적용해 보고 싶지만 핵심이 빠져서 의미가 없네요.
  • 글리 2014/10/25 20:11 #

    1) edit.js 20행 부터 23행 까지 이렇게 세 종류의 소스 적용해 봤는데 크롬에선 당연히 되고 IE8에선 툴바레이어가 클릭이 안되는데요? IE8에선 마치 IE11에서 반응하는 것과 똑같습니다.

    2) ㅋㅋ 이미 동작하는 부분을 건드린 소스를 가지고 길잡이라고 알려주시니 저로서도 황당하네요. this.m_selection.select() 이부분이 동작을 안한다니까요. inRange(this.m_selection) 이 부분도 동작을 안하구요.

    저의 감상

    ㄱ. 자기가 복붙해서 가져온 코드 설명할 능력이 없어서 마냥 된다고만 하고 상대방이 문제를 최대한 예상해서 지적해줘도 모르고
    ㄴ. 코드를 분석할 능력도 없어서 각각의 파라메터를 대입한 결과를 구분할 줄도 모르고, 이러니 줘도 못먹고~
    ㄷ. 웹표준은 관심없는 수준이 아니라 마냥 저주하는 수준이라 안보여 안들려 상태라 어거지로 돌아가고 있는걸 눈치채지도 못하고
    ㄹ. 문서객체모델(DOM)이 뭔지도 모르고 일반 객체 출력하는 법도 몰라서 이부분이 동작을 안한다니까요라는 답답한 소리만 반복할 따름이고
    ㅁ. 모르는거 투성이니 솔루션 쥐어줘도 이게 뭘 의미하는지도 모르니 모순된 소리 밖에 안튀어나오고 답이 없다.

    도대체 document.selection.type 뭐가 나오는지 출력해서 명확히 확인은 해보셨나요? 뭔 근자감으로 복붙소스랑 동등한줄 알고 개념없이 멋대로 짜넣었던 코드에서 "None"이 나오고 있다면 어쩔려고? 그땐 어떻게 처리하실건가요? 처리할 지식이 부디 있으시길. IE8에서 안된다고 징징되서 솔루션 던져준건데 게을러도 적당히 게을러야지 바닥을 뚥고 지옥으로 향할 기세시네.
  • 희망의빛™ 2014/10/25 20:49 #

    솔루션이 아니라 궁금증을 던져주시고 나서 솔루션이라니요. ㅋㅋ ^^;
  • 희망의빛™ 2014/10/25 21:04 #

    지금 alert(this.m_selection.type+" "+document.selection.createRange()); 를 중간에 넣어서 찍어보니 None [object] 라고 IE8에서 찍히네요. 제가 이전부터 궁금했던 걸 알고 계시는군요. ㅋㅋ. 이게 왜 이렇게 찍히는 건가요? ㅡ_ㅡ;
    글리님이 이전 덧글에서 제시해 주신 소스에서 이 값을 변수에 담은 의미는 무엇입니까? 저도 이렇게 찍힐 줄 알고 말씀하신 솔루션에 시큰둥했습니다만...
  • 나그네 2014/10/24 15:12 # 삭제 답글

    아... 진짜 어디가서 개발자니 프로그래머니 이런 소리 하지마세요 직업 질 평균 떨어집니다..
  • illzoo 2014/10/24 20:32 # 답글

    계속봐왔지만 이건진짜 중증이네
    지금까지 티코타면서 이렇게좋은(내가타는)티코부품은 왜계속 안나오는지,
    왜 티코부품이 안맞는 신차가 계속나오는지 투덜대며
    이건 자동차회사의 음모라고 자랑스레 짖어대고있으니 원
    업그레이드 해봐야 달라지는건 이런것들뿐이고 점점 느려지니깐요 = 차창열고달리면 시원한데 왜차가격올라가게에어콘설치하나요
  • 희망의빛™ 2014/10/24 22:20 #

    별로 빨라지진 않은 것 같은데요. 못쓰게된 기능도 많아졌지요. 차랑 비교할 게 못되는 것 같습니다. 좋아진 건 눈에 보이는 UI 정도.. 그래픽컬한 눈속임만 좋아졌지 사실 윈도우7이 좋아진 것 있나요? 윈도우 가상화가 좋다고 하는데 전 안쓰는 기능이고 윈도우 백업도 고스트만 못하고 DVD 굽는 기능도 안정적이지 못하고 어느 것 하나 제대로 좋아진 게 없는 거 같습니다 제가 보기엔...
  • illzoo 2014/10/24 23:26 #

    ㅉㅉ 내가한얘기 그대로 반영해서말하네

    내가모르는거니,안쓰는거니 안좋아요
    안들려요, 안보여요

    밸리에서좀 안보였으면좋겠네
  • 총통 R 레이퍼 2014/10/25 09:49 #

    핵발전이 문제가 많다고 부싯돌을 유지하는 나라는 망하기 마련인데 말이죠? <- 뭔 소리인지 이해 못하죠? 그냥 그런가 하세욬ㅋㅋㅋㅋㅋ
  • 2014/10/24 22:46 # 삭제 답글

    http://www.zdnet.co.kr/column/column_view.asp?artice_id=20141024082051&type=xml

    그대가 엉터리 개발자라는 신호들

    크리스 웨넘은 '그대가 엉터리 개발자라는 신호들(Signs that you're a bad programmer)'이라는 제목의 글에서 여섯 가지 신호를 이야기했다. 스스로 개발자인 저자 자신의 경험을 토대로 쓴 글이라는데, 내가 겪은 경험과도 정확하게 일치한다.

    이러한 신호를 이야기하는 것은 우리 주변에서 누가 엉터리 개발자인지 골라내자는 것이 아니다. 오히려 좋은 프로그래머가 되기 위해서 누구나 거쳐 가는 단계라고 보는 편이 정확할 것이다. 우리는 모두 한 때는 (어쩌면 지금도) 엉터리 개발자였다.

    첫 번째는 코드를 머리로 돌릴 수 있는 능력의 부재다. 엄청난 분량의 코드를 생각만으로 돌릴 수 있는 사람도 있고, 아주 짧은 코드만 돌릴 수 있는 사람도 있는데, 어쨌든 코드를 머리로 돌리는 능력은 개발자에게 기본이다. 이것은 바둑을 두는 프로기사에게 바둑판 위에 놓이지 않은 미래의 수를 읽어내는 능력이 필요한 것과 마찬가지다.

    90년대에 빌 게이츠는 마이크로소프트가 수퍼스마트(Supersmart) 프로그래머만을 고용하기를 원한다고 말한 적이 있다. 그 말을 듣고 한 기자가 게이츠에게 수퍼스마트가 어떤 사람이냐고 물었다. 그러자 그는 자기가 작성한 코드의 내용을 6개월이 지난 시점에서도 컴퓨터 없이 (마치 눈앞에서 코드를 보고 있는 것처럼) 설명할 수 있는 사람이라고 대답했다.

    그 정도까지는 아니더라도 회사에서 코드리뷰를 하다보면 자기가 아침에 작성한 코드의 내용을 설명하지 못하는 프로그래머가 있음을 알게 된다. 이런 개발자가 다른 사람이 작성한 코드를 읽을 수 없음은 물론이다. 이러한 능력의 부재는 어떤 면에서 노력으로 해결할 수 있는 것이 아니다. 이것은 개발자에게 필요한 최소한의 재능을 갖추지 못한 사례에 해당하므로 하루라도 빨리 다른 일을 시작하는 것이 더 나을 가능성이 높다.

    두 번째는 자기가 사용하는 언어의 프로그래밍 모델을 제대로 이해하지 못하는 것이다. 이런 현상은 오랜 개발 경험을 쌓은 개발자 중에서도 어렵지 않게 발견된다. 객체지향 패러다임이 탑재된 C++가 처음 등장했을 때 많은 개발자들이 C++를 이용해서 C 코드를 작성했다. 마찬가지로 오랫동안 자바 언어를 사용해온 개발자가 객체지향 패러다임을 전혀 이해하지 못하고 있는 경우가 생각보다 많다. 함수 패러다임은 말할 필요도 없다.

    오래 전에 자바 개발자를 고용하기 위한 기술인터뷰를 수행했을 때의 일이다. 내가 멀티쓰레딩과 관련한 질문을 하자 쓰레드 같은 것은 EJB 컨테이너가 알아서 관리해 주기 때문에 자기는 그런 것까지 알 필요가 없다고 대답한 사람이 있었다. 이런 사람은 이력서에 개발 경력이 5년이든 10년이든 상관이 없다. 끊임없는 학습과 자유분방한 창의력을 요구하는 프로그래밍이라는 행위를 기계적인 코딩, 단순히 반복되는 잡무, 혹은 하기 싫지만 어쩔 수 없이 하는 회사일로 대하는 사람은 앞으로 20년 동안 경험을 쌓아도 기술적으로 변화가 있을 리 없기 때문이다.

    세 번째는 학습능력의 부재다. 요즘처럼 정보가 홍수처럼 쏟아져 나오는 시대에 그 모든 내용을 미리 다 알고 있는 사람이 어디에 있겠는가. 수많은 오픈소스 라이브러리, 새로운 기술, 패턴, 사례를 모두 꿰차고 있는 사람은 어디에도 없다. 많은 것을 알고 있는 것처럼 보이는 사람은 그만큼 열의를 갖고 학습을 하기 때문이다. 인터넷 검색을 하고, 코세라 강의를 듣고, 유투브 채널에 가입하고, 세미나에 참여하고, 책을 구입해서 읽으며 쉬지 않고 공부를 한다. 여기에서 중요한 것은 공부를 통해서 습득한 지식의 분량이 아니다. 중요한 것은 공부를 하는 방법, 즉 메타 지식에 해당하는 학습능력 자체다.

    좋은 개발자는 낯선 기술이 등장하면 호기심을 품고 즐거운 심정이 되어 이곳저곳 건드려보지만, 엉터리 개발자는 입을 씰룩거리며 낯을 가린다. 이제 겨우 하나를 익혔더니 또 공부를 해야 하냐며 푸념을 한다. 낯선 대상을 두려워하는 것이 아니라 사실은 학습이라는 행위 자체를 두려워하는 것이다. 프로그래밍이라는 행위가 끝없는 학습으로 이루어져 있음을 이해하지 못하기 때문이다.

    웨넘이 네 번째로 거론한 내용은 포인터(pointer)에 대한 이해부족인데, C나 C++를 사용하지 않으면 요즘에는 포인터를 직접 다룰 일이 없으므로 넘어가자. 웨넘의 이야기를 최근의 추세에 맞게 재구성하자면 타입시스템(type system)에 대한 이해부족이라고 이야기해도 좋을 것이다.

    다섯 번째는 재귀(recursion) 알고리즘을 이해하는 능력이 없는 것이다. 이것은 맨 처음에 보았던 머리로 코드를 돌리는 능력과 밀접한 관련이 있다. 재귀를 이용해서 정수의 팩토리얼 값을 구하는 정도는 대부분의 개발자가 어렵지 않게 이해한다. 피보나치수열까지도 괜찮다. 트리구조의 노드를 순차적으로 방문하는 알고리즘도 기본적인 것까지는 무리 없이 이해한다.

    하지만 하노이의 탑과 같은 알고리즘이 등장하면 숨이 막히기 시작한다. 꼬리재귀(tail recursion)가 왜 효율적인지, 일반적인 재귀 알고리즘을 어떻게 꼬리재귀 알고리즘으로 변환할 수 있는지 등을 이야기하다보면 한계를 느낀다. 이런 사람들은 개발자가 되어서 실전에 배치되어도 운영체제의 루프백(loopback) 주소라는 개념을 이해하지 못해서 애를 먹는다. 재귀라는 알고리즘의 작동방식이 머릿속에서 그려지지 않는 탓이다.

    마지막은 코드에 대한 불신이다. 엉터리 개발자들은 정작 믿지 않아야 하는 코드를 신뢰하고, 믿어도 좋은 코드를 불신한다. 유닛테스트 코드를 작성하라고 시키면 실제로 검사되어야 하는 코드를 테스트하는 것이 아니라, 언어자체의 문법이나 라이브러리 코드의 API를 확인하는데 시간을 보낸다. 버그 투성이인 자신의 코드에 애착을 품고, 철저하게 검증된 라이브러리 코드를 의심한다.

    전부는 아니더라도 이러한 여섯 가지 중에서 한 두 항목에서 뜨끔한 기분을 느낀 사람이 있을 것이다. 다시 한 번 말하지만 이 글의 목적은 엉터리 개발자를 추궁하자는 것이 아니다. 좋은 프로그래머가 되기 위해서 우리가 밟아온 과정, 혹은 앞으로 밟아야 하는 과정을 환기하여 다 같이 행복한 프로그래밍을 하자는 것이 목적이다. 다음에 기회가 있으면 “그대가 훌륭한 개발자라는 신호들”에 대해서도 이야기하도록 하겠다.
  • 희망의빛™ 2014/10/25 07:50 #

    좋은 개발자는 낯선 기술이 등장하면 호기심을 품고 즐거운 심정이 되어 이곳저곳 건드려보지만, 엉터리 개발자는 입을 씰룩거리며 낯을 가린다. 이제 겨우 하나를 익혔더니 또 공부를 해야 하냐며 푸념을 한다. 낯선 대상을 두려워하는 것이 아니라 사실은 학습이라는 행위 자체를 두려워하는 것이다. 프로그래밍이라는 행위가 끝없는 학습으로 이루어져 있음을 이해하지 못하기 때문이다.
    =============================================================

    전 이 부분만 해당이 되는 것 같네요. 신기술이 늘 좋은 건 아닌것 같아서요. 내막을 들여다보면 말이죠. 전통적으로 내려온 기술이 오히려 빠르고 더 장점이 많은 것도 사실이죠.
  • 총통 R 레이퍼 2014/10/25 09:51 #

    전통적으로 내려온 기술이 빠르고 더 장점이 많은거 함 이야기나 해보시고 이런 말을 하시죠?
    다른 사람들 다 빠르다고 하는데 너님이 공부를 안해서 못써먹는걸 왜 세상을 탓하시나?
    당신같은 사람때문에 사람은 배워야 한다고 어르신들이 귀에 딱지가 생기도록 말하는겁니다.
  • Hide_D 2014/10/26 19:30 #

    희망의빛. '전부'요.

    1) 첫번째.
    저 짧은 코드에서도 코드 흐름을 파악하지 못하고 계십니다.
    머리속으로 코드를 돌리는 능력은 '전무'하다고 판단됩니다.

    2) 두번째
    JavaScript에 대해서 이해를 하지 못하고 계십니다.
    변수 스코프, this의 용법, 메시지 전달 방식 어느 하나 제대로 알고 계신게 없습니다.
    PHP는 물론이며, '네트워크'에 대한 상식 조차 부족합니다.

    3) 세번째
    수 많은 오픈 소스중, 단 하나라도 이해하고 계신게 있습니까?
    여태까지 댓글로 '제발' DOM에 대해 이해하라, jQuery를 사용해 보아라 라는 말이 계속 나왔지만,
    정말로 써보신 적이 있습니까?

    4) 네번째
    왜 위의 에러가 나는지를 생각해보면, 타입 시스템에 대해 제대로 이해를 못하고 계신것 또한 분며합니다 ㅡㅡ
    왜 '인자'가 잘못되었다고 뜰까요? 함수 레퍼런스는 찾아보셨습니까?

    5) 다섯번째.
    '다행히'도 웹 프로그램에는 보통 재귀함수가 없으니(더군다나 꼬리재귀는 더더욱) 배우실 필요는 없습니다.
    천만 다행이네요. 몰라도 되어서.


    이쯤되면 그냥 개발자도, 프로그래머도 아무것도 아니라는 뜻입니다.

    제발 공부좀 하고, 모르는게 뭔지 파악좀 해보세요.
    지금 상태를 보면 방정식도 모르면서 미분, 적분을 하겠다는 사람을 보는 것 같습니다.
  • 2014/10/24 22:54 # 삭제 답글

    윈도우 가상화가 좋다고 하는데 전 안쓰는 기능이고 윈도우 백업도 고스트만 못하고 DVD 굽는 기능도 안정적이지 못하고 어느 것 하나 제대로 좋아진 게 없는 거 같습니다 제가 보기엔...

    1. 가상화를 쓰는 사람들에겐 좋음
    2. win7에서 고스트 잘 돌아가니 win7 백업 대신 고스트 쓰면 됨
    3. XP에서 DVD굽기 하려면 어차피 네로 따위 써야 함, win7 에서 네로가 더 안정적으로 잘 돌아감

    뭐가 안좋다는건지..
  • 희망의빛™ 2014/10/25 07:52 #

    요샌 네로도 한물 간 거 같음. 덩치도 무쟈게 크고 안정성이 많이 떨어졌습니다. Ashampoo가 요샌 쓸만하더군요. 프로그램도 비교적 작고 무엇보다 맘에 드는 건 뛰어난 안정성...
  • Miyun_86 2014/10/25 21:23 # 삭제 답글

    이야... 아니, 함수 리턴값이랑 인자 타입도 구분 못하면서 개발자니 뭐니 떠벌린겁니까...?!?!

    진지하게 충고합니다. 책 보십쇼. 이건 개발자 수준 문제가 아니라 자기가 개발하는 기본 개념도 없는 무식 인증입니다. 무식인증 ㅡㅡ

    모르는건 창피한게 아닙니다. 그런데 모르면서 아는 척 하고 타인의 충고도 못 알아듣고 찾아볼 생각도 안하는건 창피한겁니다. 왜 욕 사서 먹으세요? 나이도 지긋하신 분께서...?
  • 희망의빛™ 2014/10/27 23:17 #

    제가 책 보는 걸 지루해 해서 말이죠. 주로 구글을 활용하죠. 그리고 어떤 개발자든 자신이 모르는 부분은 있답니다. 신이 아닌 이상... 그건 당신도 마찬가지일 거요. 왜 다들 저를 비하하는 식으로 얘기해서 어떤 목적을 달성하려고 하는지 모르겠지만 참으로 구역질 납니다. 좀 창피한 줄 아세요 다들... 그리고 제가 개발자라고 떠벌렸다니요. 말 만들어 내지 마시죠. 개발자는 그럼 땅에서 솟는 답니까? ㅋㅋㅋㅋㅋㅋㅋㅋㅋ. 당신네들 말하는 수준이 꼭 저학년 애들이 말하는 수준이라는 건 알고 계신지... 안보인다고 함부로 말하면 언제나 개망신 당할 수밖에 없습니다.

    제가 해결책을 모르고 있다면 해결책을 제시해 주는 게 정상적인 사람의 행동이지 이렇게 행동하는 님들을 보면 마치 시시콜콜한걸 물고 늘어지며 으르렁 거리는 늑대가 생각나군요. 늑대... 그러고보니 인간늑대네요. 정말 행동이 늑대 이상입니다. 피(돈-?)에 굶주린 늑대 이상의 인간 괴물이 생각이 납니다. 저 위에 총통R레이퍼 님도 해당이 되는 이야기입니다. 총통R레이퍼님 준비는 되셨겠죠? 전 언제나 제 잘못을 인정할 준비가 돼 있답니다. 그러니까 부담갖지 마시구요. ^^
  • Hide_D 2014/10/26 19:31 #

    책 보면, 나옵니다. 제발 책 좀 보세요.

    책도 안보는 사람이 구글링은 해서 뭣합니까. 기본이 안닦여 있는데...
  • 총통 R 레이퍼 2014/10/27 00:40 #

    니가 언제 잘못을 인정했냐?
    공부를 하세요 -> 책보는게 싫어요
    해결책을 모르고 있다면 해결책을 제시해 주는게 정상 -> 책에 나오니까 보시오 -> 책보는게 싫어요.

    이게 질문하는 인간이 그것도 프로그램 만질 줄 안다는 사람이 할 답변은 아니지 않나? 정신나갔넼ㅋㅋㅋㅋㅋㅋ

    지금 대다수의 답변이 '책 보고 공부하면 해결되는 문제'라고 하는데 '누구든지 모르는 부분이 있다'라니 웃기는 일 아뇨?
    책을 보라는데 왜 동문서답을 하고 자빠지는지?

    그리고 날 끌어들이냐? 하하. 니가 뭘 잘못했는지 말해줘도 알아처먹지를 못하니 니가 잘못을 인정하지 못하는거라는 생각은 안해봤지?

    '시대에 역행한다'는 것 자체가 인류이자 인간으로서 글러먹은것인데 이거...인정할 생각 있으슈?
    근데 그거 알아두쇼. 너님이 시대에 역행한다는 걸 인정하는 순간 발전의 최전방인 IT는 말 꺼내서도 안되고 MS한테 불평가지는 소리도 못하고 호환 안된다고 징징거리는것도 불가능하니까.


  • 희망의빛™ 2014/10/26 09:24 # 답글

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
    <HTML>
    <HEAD>
    <TITLE> 크롬에서 alert 와 document.write 테스트 </TITLE>
    <script language="JavaScript">
    function CSelection()
    {
    this.m_selection = null;
    this.GetSelection = get_selection;
    this.PutSelection = put_selection;
    }

    function get_selection()
    {
    alert(memoiW.document.selection.type+" & "+memoiW.document.selection.createRange());
    document.getElementById('test').innerHTML = memoiW.document.selection.type+" & "+memoiW.document.selection.createRange();
    }

    function put_selection()
    {
    if(typeof window.getSelection != "undefined"){
    this.m_selection = memoiW.window.getSelection();
    this.m_selection.type = typeof memoiW.document.getSelection;
    } else if(typeof document.selection != "Control"){
    this.m_selection = memoiW.document.selection.createRange();
    this.m_selection.type = memoiW.document.selection.type;
    }
    }

    function deactivate_handler()
    {
    selectionObj.PutSelection();
    }

    function DocReload()
    {
    memoiE = document.getElementById("memoi");
    memoiW = memoiE.contentWindow;
    memoE = document.getElementById("memo");
    DocLoading();
    }

    function DocLoading()
    {
    selectionObj = new CSelection();
    }
    </script>
    </HEAD>
    <BODY>
    <SCRIPT language="JavaScript">
    <!--
    DocReloadInterval = setInterval("DocReload()", 300);
    //-->
    </SCRIPT>
    크롬에서 alert 테스트<br>
    [DIV 영역]<br>
    <div id=test></div>
    [DIV 영역 끝]<br>
    <input type=button value="selectionObj.GetSelection();" onclick="selectionObj.GetSelection();">
    <iframe id="memoi" style='width:100%; height:100%; display:none;' onbeforedeactivate='deactivate_handler()' scrolling='yes' frameborder='no' border='0' ALLOWTRANSPARENCY='true'></iframe>
    <textarea id='memo' style='width:100%; height:100%; display:block;'></textarea>
    </BODY>
    </HTML>
    =========================================================================================

    제가 이렇게 테스트 소스를 만들어 IE브라우저와 크롬의 캐쉬를 비우고 Getselection() 버튼을 누르면 IE8 에선 알림창 후 None & [object] 라고 출력이 되는데 크롬에선 & 조차도 출력이 안되면서 alert도 안뜨고 div 영역에 아무것도 출력이 되지 않습니다. 여러분들도 위의 소스 함 실행해 보십시요. 이것도 좀 이해가 안갑니다. 소스를 최대한 단순화 시켰는데도 뭐가 어떻게 된건지 모르겠네요.
  • 오오 2014/10/26 10:21 # 답글

    파이어폭스: TypeError: memoiW.document.selection is undefined
    크롬: Uncaught TypeError: Cannot read property 'type' of undefined
    사파리: TypeError: undefined is not an object (evaluating 'memoiW.document.selection.type')

    Line 10에서 저게 말이 안된다고 동작을 안합니다.
    문서를 보면 안하는 것이 정상이라 보입니다.
    저게 실패하므로 alert도 실패하는 것이죠.

    IE8은 편법으로 일단 그런 에러 상황에서 None을 반환하고 통과는 되도록 구현했다고 할 수도 있을지 모르지만 (그러니 alert 가 뜨는 것) 에러는 그냥 멈추고 에러 메시지를 알려주는 것이 좋죠.

    이해가 안된다고 질문하기 전에 에러 메시지를 확인해 보시라고 말씀드리고 싶네요.
  • 희망의빛™ 2014/10/26 12:06 #

    그러고 보니 크롬에 자바스크립트 콘솔창이 있었네요. 예전에 이걸로 한참 디버깅 했던 기억이 나는데 그리 오래되지 않았는데 그새 그 창을 확인하는 걸 깜빡했습니다. ^^; 도움말씀 감사합니다. 지금 원인을 찾고 있는 중입니다.
  • Hide_D 2014/10/26 19:59 # 답글

    아직도 파악이 잘 안되는듯 하시니... 정리해서 말씀드립니다.

    "코드 자체가 버그 덩어리입니다."
    20번째줄은 인자 타입조차 안맞고
    34번째 줄은 무조건 'function'이 나올텐데 대체 무슨 값을 받고 싶었던 건지도 모르겠구요.

    파이어폭스, 크롬 전부 동작 안하는 코드입니다.
    제 예상에는 IE8에서도 동작하는 코드가 아닌데, 에러가 나더라도 나머지 코드를 돌리느냐, 아니면 에러가 나면 멈추느냐의 차이일겁니다.

    (혹시라도 에러나도 돌리는게 맞다고 우기지는 마시기 바랍니다.)

    그리고 여전히 저 코드가 정확히 하고자 하는게 뭔지를 잘 모르겠는데,
    혹시라도 주인장께서 저 코드가 무슨 코드인지 이해하고 있다면, 차라리 백지부터 새로 만드셔야 한다고 봅니다.

    IE11에서 먼저 돌아가는 코드를 만들면, 파이어폭스, 크롬에도 큰 수정 없이 돌아가고,
    IE8에도 돌아가도록 살짝 수정하면 됩니다.
  • diamonds8 2014/11/02 22:32 # 삭제 답글

    야이 시발새끼야. 니는 만일 그딴 인성으로 프로그래밍 한다고 자칭 하면 제발 내 앞에 나타나진 마라. 내가 니 머리 뇌수 터질때 까지 후려갈길 것 같거든.

    니같은 놈 보면 진짜 화가 치솟다 못해 웃음만 나올 지경이다.
댓글 입력 영역
* 비로그인 덧글의 IP 전체보기를 설정한 이글루입니다.


웹로그 검색