Search

'전체'에 해당되는 글 119건

  1. 2010.03.15 초록비 - 비쥬
  2. 2010.03.10 Social MSDN Forum 활동
  3. 2010.03.09 너에게 감사해 - 동물원
  4. 2010.03.08 Simple Tip -- ResourceDictionary동적 생성을 위한 x:Class의 활용
  5. 2010.03.04 2010년 2월 4주 알라딘 TTB리뷰 선정 (4)
  6. 2010.02.25 Using a ViewModel as a value converter
  7. 2010.02.23 안톤 체호프 - 6호 병동
  8. 2010.02.23 LambdaValueConverter
  9. 2010.02.23 달콤함이라면 바로 이런 거지 - 사이 (2)
  10. 2010.02.10 아쉽고, 아쉽다. -- 예수 충격 (2)
  11. 2010.02.10 대화를 하자고, 불가사의한 소년 - 소크라테스편 (6)
  12. 2010.02.09 WPF Template의 이해
  13. 2010.02.09 너를 품에 안으면
  14. 2010.01.17 그 녀석, 그리고 Creep
  15. 2010.01.15 아이티의 지진 -- 누구를 위하여 종은 울리나
  16. 2009.12.31 Blue Eyes Blue- Eric Clapton
  17. 2009.12.24 나쓰메 소세키의 '마음'을 읽은 그들의 대화 -2 (2)
  18. 2009.12.16 나쓰메 소세키의 '마음'을 읽은 그들의 대화 -1
  19. 2009.12.15 K, 질문을 던짐으로 다른 이를 깨우치다. (2)
  20. 2009.12.14 Code Contract -2
  21. 2009.12.09 Beyond the Assertion, Code Contract -1
  22. 2009.12.04 Running On Faith - Eric clapton
  23. 2009.11.30 Visual Studio Solution File(.sln) Parser
  24. 2009.11.30 나쓰메 소세키의 '마음'을 읽고
  25. 2009.11.11 WPF Dialog 컨트롤들
  26. 2009.11.10 송영길 의원 대정부 질문 (2)
  27. 2009.11.04 한글 오토마타 (4)
  28. 2009.10.31 코엑스의 도인 (7)
  29. 2009.10.07 당신에게 책 읽기란 무엇입니까?
  30. 2009.10.07 정말 제 3의 길은 없나?

초록비 - 비쥬

노래이야기 2010.03.15 21:18 Posted by 아일레프


저작자 표시
신고

Social MSDN Forum 활동

프로그래밍 2010.03.10 06:52 Posted by 아일레프

어떤 Community에도 정착하지 못하다가 현재 Social MSDN Forum에서 활동하고 있다.

 

Activity Rss는 다음과 같다.

http://services.social.microsoft.com/Feeds/Activities?user=illef&lcid=en-US&brand=Msdn&format=rss20

 

그리고 정말 유익한 Dr.WPF Activity Rss도 소개한다.

http://services.social.microsoft.com/Feeds/Activities?user=Dr.%20WPF&lcid=en-US&brand=Msdn&format=rss20


저작자 표시
신고

너에게 감사해 - 동물원

노래이야기 2010.03.09 19:03 Posted by 아일레프

견디기 힘들었어 니가 곁에 없다는거
함께한 기억조차 외면하며 살아왔지
이제야 알겠어 함께 했던 추억들이
외로운 나의 삶에 빛이 되는 걸 알겠어 감사해

이유없이 눈물이 나는 날은 우리함께 했던 날을 생각해
견디기 힘든 이별이라 외면했지만 행복했던 순간들
문득 그댈 떠올리며 나지막이 너의 이름을 불러보았지
오래 서로 잊은채로 살아왔지만
그 모두 사랑이었어

너에게 감사해 지난 기억만으로도
초라한 내 모습이 밝게 빛날 수 있엇지
너에게 감사해 너의 미소만으로도
흐려진 내 영혼이 날아오를 수 있었지
너에게 감사해

기억 속에 희미하게 본 우리 따스한 빛이 내게 스며와
차갑게 얼어붙은 내 지침 영혼을 잠시 녹여주었어
문득 그대 떠올리며 나지막이 너의 이름을 불러보았지
오래 서로 잊은채로 살았지만
그 모두 사랑이었어

너에게 감사해 지난 기억만으로도
초라한 내 모습이 밝게 빛날 수 있었지
너에게 감사해 너의 미소만으로도
흐려진 내 영혼이 날아오를 수 있었지
너에게 감사해
저작자 표시
신고

2010.3.8 내용 추가.

x:Class
를 이용한 ResourceDictionary 동적 생성의 또 하나의 응용으로 Storyboard - Completed Event problem 가 있습니다.

 
 Storyboard - Completed Event problem 단지 Storyboard에 대한 예였으나 이를 “Resource에 추가한 객체에 이벤트를 추가시키는 법으로 일반화 시켜서 생각해 볼 수 있겠습니다.

-------------------------------------------------------------------------------------------------------

이것은 그냥 간단한 팁입니다.

WPF로 프로그래밍을 하다 보면 간혹 동적으로 ResourceDictionary를 사용하고 싶을 때가 있습니다. 런타임상에 별도의 ResourceDictionary를 로드해 해당 Dictionary의 특정 Key에 해당되는 Value를 사용하고 싶다는 것이지요. 이럴때 보통 XamlReader를 이용해 ResourceDictionary.xaml을 Load한 뒤 해당 ResourceDictionary로 캐스팅 해서 사용하게 되는데요, 이런 목적이라면 x:Class를 활용하는 것이 더 괜찮을 수 있습니다.

먼저 ResourceDictionary를 프로젝트에 추가합니다.

 

그리고 동일한 이름으로 '동일한이름.xaml.cs'를 추가합니다.

아래와 같이 Project에 페어링 된 형태로 추가된 것을 확인할 수 있습니다.

이를 확인하고 Dictionary.xaml.cs를 다음과 같이 수정합니다.

public partial class Dictionary : ResourceDictionary
{
    
public Dictionary() 
    
{
         
InitializeComponent(); 
     }
 
}

이 때 InitializeComponent 메소드가 존재하지 않기 때문에 Error List에 InitializeComponent메소드가 존재하지 않는다는 에러가 추가됨을 확인할 수 있습니다.

InitializeComponent메소드를 만들어 줘야 합니다. 어떻게 만들어 주냐? Dictionary.xaml에 X:Class를 추가해주면 됩니다.

<ResourceDictionary

x:Class="HierarchicalDataGridTest.Dictionary"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

 

</ResourceDictionary>

빌드가 성공함을 알 수 있습니다. 이제 코드에서 ResourceDictionary dic = new Dictionary(); 이와 같이 ResourceDictionary를 손쉽게 만들어 사용할 수 있습니다.

좀 더 나가면 이렇게 만든 Dictionary는 WPF Component Repository의 역할을 수행할 수도 있습니다.

public partial class Dictionary : ResourceDictionary

    
public Dictionary() 
    

         
InitializeComponent();
    

    
public Style MyButtonStyle 
    

         
get { return this["MyButton"] as Style; } 
    
}
}

신고

2010년 2월 4주 알라딘 TTB리뷰 선정

분류없음 2010.03.04 00:13 Posted by 아일레프

지난번 대화를 하자고, 불가사의한 소년 - 소크라테스편 포스트가 2010년 2월 4 알라딘 TTB리뷰로 선정되었다.

이것을 ''의 범주 내에 포함시킬 수 있다면 초등학교 4학년 때 민물강가에서 가족들과 고래 구워먹는 그림 이후 처음 받는 상이 된다.

치열한 자본주의 사회에서 단지 1만원의 가치에 불과하지만 내게 꽤나 큰 기쁨이 될 수 있다는 사실에 스스로 많이 놀랐다. 덕분에 오늘 하루는 어제보다 더 싱글벙글.

 

고마워요 소크라테스. :)


저작자 표시
신고

Using a ViewModel as a value converter

프로그래밍 2010.02.25 18:24 Posted by 아일레프

<TextBlock Background="LightBlue" Text="{Binding Path=Text}" TextAlignment="Center"

                   Width="{local:BindingEx Binding={Binding ElementName=window, Path=ActualWidth}, ConverterMethod=AdjustTextWith}"/>

 

MVVM Pattern을 사용하면서 부딛히는 문제 중 하나는 많은 수의 Converter의 필요에서 오는 귀찮음과 비효율성이다. 컨버터가 필요할 때마다 별도의 클래스를 만들어 주어야하며, Resource에 추가해야 했으며, StaticResource MarkupExtension으로 사용해야 했다. 이전에 이것에 대한 해법으로 ConverterManager라는 글을 쓴 바 있지만 이것은 Converter Resource에 중복 생성하는 것에 대한 문제를 해결 했을 뿐, 많은 수의 Converter 클래스를 만들어야 한다는 비 효율성을 제거하지는 못했다.

 

이전에 소개한 LambdaValueConverter의 경우 LambdaConverter MarkupExtension을 사용해 XAML내에서 Expression을 사용 할 수 있게끔 했다. 여기에 이어 이 문제를 해결하기 위한 새로운 접근 방법을 소개한다. ViewModel의 특정 메소드를 Converter로 쓸 수 있게 하는 방법이 그것이다. John Smith on WPF 에서 확인 할 수있다.


저작자 표시
신고

안톤 체호프 - 6호 병동

즐거운 책 이야기 2010.02.23 22:43 Posted by 아일레프

개를 데리고 다니는 부인 - 10점안톤 파블로비치 체홉 지음, 오종우 옮김/열린책들

"그는 지성과 정직을 대단히 사랑하지만, 자기 주위에 지적이고 정직한 현실을 만들어 내기에는 품성이나 자신감이 부족하다. 명령하고 금지하는 일을 하지 못한다."
 
이것이 그 의사에 대한 묘사이다. 그가 거울과 같이 내가 싫어하는 나의 모습을 보여주었기에 난 빠져들 수 밖에 없었다. 두 번째, 그리고 세 번째 이 소설을 읽고 나서, 마치 타임머신을 타고 미래로 훌쩍 날라가 마치 나의 최후를 보는 듯한 느낌마저 들었다. 머리 속에 "이대로 살아서는 안되겠다."라는 문장이 퍼뜩 떠오른다. 내 미래를 바꿔야겠다.
 
그는 의사이다. 원래 의사가 되고 싶었던 것은 아니다. 성직자가 되고 싶었으나 아버지가 원하지 않아 의사가 되었다. 의사는 죽음과 마주하는 치열한 직업이지만 그는 이 세계에서 치열하게 살아본 적이 없고 그래야 할 필요도 느끼지 못한다. 그것은 선천적으로 그가 '게으르기'때문이다. 한마디 하자면, 게으른 자에게 지식과 사유의 기술을 물려주면 안된다. 한 수 앞서가는 수 읽기로 그는 자신의 게으름을 기필코 정당화 시키고 말리라. 잠시 그의 치밀한 수 읽기와 마주해본다.
 
"사실, 죽음이 누구에게나 정상적이고 당연한 결말이라면 무엇 때문에 사람들이 죽는 것을 막으려 한단 말인가? 어떤 장사치나 관리가 5년이나 10년을 산다 한들 무슨 의미가 있겠는가? 의학의 목적을 약으로 고통을 덜어 주는 데서 찾는다면, 다음과 같은 질문이 생기는 것은 당연하다. 고통을 무엇 때문에 줄이려 하는가? 고통은 사람을 완성으로 이끌며 만약 인류가 자신의 고통을 경감시킬 알게 된다면 자신을 보호해 주고 행복을 가져다 주었던 종교와 철학을 아주 저버릴 것이다. ... 이런 생각에 짓눌려 안드레이 에피미치는 기운을 잃고, 병원에 매일 나가지도 않았다."
 
치열한 가위, 바위, 보의 순환 끝에 내민 그의 주먹이 "병원에 매일 나가지도 않았다"라는 것은 비극이 아닐 수가 없다. 고통은 중요하고, 사람을 완성으로 이끈다는 그럴싸한 결론의 이면에는 치명적인 게으름과 고통은 숭고한 것이지만 막상 그 자신은 그것을 느끼기 싫어한다는, 역겨운 아이러니가 있다. 그 아이러니를 전혀 깨닫지 못한 채로 자신만의 세계 안에서 삶과 연결되지 않는 그만의 철학을 한다. 그리고 어느 날 6호 병동에서 이반을 만난다. 의사는 지적이고, 사상이 있으며, 사유 할 수 있기에 자신의 세계에서 함께 뛰어 놀 수 있는 지적 동반자를 만나 너무 반갑다. 그 이반은 과거 의사와 같던 사람이었다. 허나 지금은 달랐다. 적어도 의사가 모르는 무엇인가를 알고 있었다.
 
의사 : "우리를 자극하는 외부의 모든 것들이 허무하다는 사실을 깨닫게 것입니다. 인생은 이성적으로 이해하려고 노력해야해요."
이반 : "웃기는 소리하지 마시오, 내가 아는 것은 신이 나를 따뜻한 생명체로 만들었다는 겁니다. 자극에 반응해야 합니다. 그래서 나는 반응하고 있는 겁니다! 고통에 대해 나는 비명과 눈물로 대답해요, 비열함에는 분노로, 혐오에는 구역질로! 이것이 삶입니다. 당신은 삶이 무엇인지도 모르고 본적도 없어요."
 
그렇다. 이반은 바로 고통의 실체를 알고 있었던 것이다. 이것 봐라, 고통과 마주해야만 삶을 알게 되는 것인가. 그렇다면 다행인 것인가? 지성만이 흥미롭고 주목할 만한 것이라 말하는 그 의사는 인생을 완성시킨다는 그 고통과 마주 할 수 있게 되었다. 처음 그것과 마주한 그는 과연 그 다운 사유를 무기로 그것을 회피하려 애쓴다.
 
" 따위 감정은 모두 사라지는 것이야, 나도, 그들도 모두 죽어 자연으로 돌아가 흔적도 남지 않겠지. 문화도, 도덕도, 규범도 사라지는 거야. 모든 것이 하찮고 무의미한 것이라고. 그런데,, 젠장!"
 
마침내 바라본 현실 앞에서 사유와 라는 그의 무기는 형편없이 부러진다. 다른 무기를 들어 그 현실에 저항했으면... 그러나,
 
"벗어날 수가 없어, 벗어날 없어, 우리는, 인간이란 연약해,"
 
그가 마지막에 낳은 사유의 열매가 인간이란 연약해라는 결론이라니, 무어라 말할 수 있을까. 그는 난생 처음으로 매를 맞는다. 아버지에게도 맞지 않은 매를 맞은 그는 처음으로 만난 고통의 실재 앞에서 어쩔 줄을 모른다. 육체의 고통을 치료하기 위한 직업을 가진 그는 처음 만나본 그 육신의 고통 앞에서 어쩔 줄을 모른다.
 
어떻게 20 이상의 세월이 흐르는 동안 이런 사실을 알지도 못했고, 알려고 하지도 않았던 것일까.
 
소설 마지막 그 의사의 죽음을 바라보며 멀지만 얼마 남지 않은 나의 죽음 또한 본다. 그리고 이렇게 죽어서는 안되겠다고 생각한다. 이렇게 죽을 수는 없다. 세상과의 고리가 끊긴 자신만의 철학은 쓸모가 없다. 신이 내게 삶을 골방에서 책만 보며 수는 없다. 낚시꾼의 낚시 바늘에 매달린 물고기처럼, 둔탁한 칼에 마침내 목과 내장이 뜯겨 나간다는 결론이 훤히 보이지만 파딱거림으로 작은 순간이라도 필사적으로 살아야겠다고 결심해본다. 내 미래, 그리고 죽음을 바꿔야겠다.
저작자 표시
신고

LambdaValueConverter

프로그래밍 2010.02.23 18:09 Posted by 아일레프
Binding Lambdas1


맙소사, Converter={AvalonLamdas:LamdaValueConverter (param/2)-20}}이라니, 놀랍지 아니한가? Converter내에 수식을 넣을 수 있는 것이다. 이제야 발견하고, 이런 걸 만들 생각조차 하지 않았다는 것이 부끄럽다.(해당 Converter는 벌써 2008년에 만들어진 것이다.) Dynamic Expression API 의 한가지 쓰임이라고 할 수 있는데 유용하게 사용 할 수 있을 것 같아 이곳에 소개한다.

 

Embed code in XAML 페이지를 통해 확인할 수 있다.

저작자 표시
신고

달콤함이라면 바로 이런 거지 - 사이

노래이야기 2010.02.23 16:38 Posted by 아일레프





아, 좋다. 내가 illef외에 사용하는 닉네임을 가진 가수의 이름이라 더욱 친근하다. 달콤함이 있다면 바로 이런 것지. 


도봉구 쌍문시장 '고쉬제과점'에 가면

팥빙수가 단돈 이천 원
시럽은 빼 달라고 말할 줄 아는 그 입술
달콤함이 있다면 바로 이런 거지

새벽에 일어나 텃밭에 가서
대충 일하고 파꽃 옆에서 도시락을 까먹네
돌아오는 길에 막걸리 따라주는 눈동자
달콤함이 있다면 바로 이런 거지

인도에서 돌아온 당신의 편지
빅뱅 이론을 뒷받침할 중요한 증거
그리고 내가 네이버를 뒤져 만든 두부탕수육
달콤함이 있다면 바로 이런 거지

아침에 콩밭메고 냇물에 목욕한 뒤
빛나는 식탁과 노래와 태극권
보름달 아래 다랑이논 옆에서 나누던 키스
달콤함이 있다면 바로 이런 거지

50만원 낡은 트럭에 이삿짐을 가득 싣고
고속도로를 달리다가 타이어에 펑크
겨우 도착한 우리집은 한쪽 벽이 무너져내린 집
달콤함이 있다면 바로 이런 거지

나무 부스러기 줏어모아 아궁이에 불을 때고
가마솥에 물을 퍼서 한 대야로
세수하고 머리 감고 발을 씻고 빨래까지 다하네
달콤함이 있다면 바로 이런 거지

삽질과 괭이질로 어깨는 벌어지고
쑥과 쇠뜨기 골라내며 인내심을 배우네
감자 고구마 상추 시금치 고추 참께 들께 콩
옥수수 파 토마토 가지 쑥갓 우엉 아욱 당근 수박 호박 배추 열무 
그리고 
우리 두 사람

달콤함이 있다면 바로 이런 거지

달콤함이 있다면 바로 이런 거지
저작자 표시
신고

아쉽고, 아쉽다. -- 예수 충격

즐거운 책 이야기 2010.02.10 20:39 Posted by 아일레프

 

예수 충격 - 경이와 충격을 자아내지 않으면 예수가 아니다
피터 크리프트 지음, 김성웅 옮김 / 김영사 / 2009 11

 평범한 내용에 비해 "충격"이라는 과장된 단어가 가져다 주는 기대감이 터무니 없이 컸다. 저자는 약 10년 동안 이 책의 내용을 구상하고, 써왔다고 했는데, 그 결과는 내 기대에 비해 너무나 초라해보인다부실하고도 진부한 내용이 그 제목 만큼이나 충격적이다

 
이 책을 구입하려는 분이 있다면, C.S 루이스의
"순전한 기독교" 또는 C.S루이스의 다른 서적들, 그리고 필입얀시의 서적들을 구입하라고 권하고 싶다. 개인적으로는 필입얀시의 ", 내안에 하나님이 없다"를 추천한다.


저작자 표시
신고

소크라테스의 변명 - 10점플라톤 지음/문예출판사



저 애처러운 눈으로 “대화를 하자”고 말을 하는 소크라테스의 만화 속 표정을 어찌 잊을 수 있을까.


내가 진짜 ‘대화’의 필요성을 느끼게 된 것은 오래되지 않은 최근이다. 어느 날 친구들과 일상 대화를 하는데, 난 내 말이 그에게 스며드는 것이 아니라 오히려 튕겨져 나오는 것을 알아차렸다. 내가 하는 이야기가 그를 통과해 전혀 상관없는 다른 이야기로 내게 되돌아오고 있었던 것이었다. 시간이 지나가며 다른 이와의 대화를 관찰해보니 이런 일은 굉장히 비일비재했다. 이전에 이 사실을 알지 못했던 것은 그를 통과해 되돌아오는 그 이야기에 전혀 상관하지 않고 오직 내 말만을 했기 때문이었다. 오호, 이 사실을 알고 상대방의 말에 반응하는 나를 관찰해 보았다. 나라고 다를 손가. 나 또한 그의 이야기를 거칠게 뱉어내고 있었다. 그러나 이제 알았다. 대화를 하려 했기에 대화가 어렵다는 사실을 알았고, 남들이 내 말에 관심이 없다는 것과 나 또한 남의 말에 진실된 관심이 없다는 사실을 깨달았다. 알았으니 이제 되었다. 이젠 어렵더라도 문제를 해결하면 된다.

그런데 대화란 무엇인가? 대화의 사전적 의미는 다음과 같다.

대화(Dialogue)둘 이상의 실체 사이의 상호적인 언어 소통이다.

사전적 의미는 위와 같지만 어떠한 사물이나 관념을 규정하는 것은 그것을 사용하는 외부에 있기 마련이다. 예를 들어 “망치”는 물체를 치는 데 쓰이는 도구이지만, 그것을 사용하는 외부에 따라서 살인 도구로 쓰일 수도 있고, 건물을 만드는 도구로 쓰일 수도 있다. 눈에 보이지 않는 ‘대화’ 역시 마찬가지로 그것을 사용하는 외부의 실천적 양식에 따라서 전혀 다른 수단으로 사용된다. 이에 3가지 경우를 살펴본다.

 

내 마음 속 숨어있는 자아의 경우

지구에 존재하는 모든 존재들에게 씨를 뿌려 자손을 낳고 싶은 욕구는 너무나도 당연하기 때문일까? 생명을 낳는 다는 그 욕구 너머 나의 생각을 전파하고, 그 생각으로 남을 지배하고 싶다는 욕망이 내 마음 속에 있다는 것을 부인할 수 없다. “우리가 간직 해야 할 소중한 것 있다면, 내 삶을 누군가에게 나눠줄 수 있는 것”내가 좋아하는 이 노래 가사는 이 욕구를 교묘하게 숨기고 있는 듯 보인다. ‘삶을 나눈다’는 그 빛나는 드레스를 벗기면 내 삶을 남에게 적용하고 싶다는, 내 생각의 씨앗을 그의 머리 속에 심고 싶다는, 그것으로써 그에게 단순한 공감을 넘어서는 찬양을 받고 싶다는 어처구니 없는 욕망이 내재되어 있다. 이 경우 대화는 이 목적 아래서 자신을 전파하는 도구이다. 코엑스의 도인과 대화를 해본 적 있는가? 그들은 순진하고도 청결한 목적 아래 감추어진 이 욕구를 보지 못한 채로 웃음을 지으며 “나 처럼 살아봐요, 행복해질 거에요” 라고 말한다. 나 역시 다른 이에게 저렇게 말하는데 내가 저 말을 온전히 믿을 손가? 이 경우 대화란 남보다 우월해 보이는 듯한 나를 남에게 강요하기 위한 도구이다.

 

소피스트의 경우

소피스트에게 귀엽고 사랑스러운 구석이 있다면 이들이 솔직하다는 점이다. 저 옛날 그 때 그 시절에 그리스인들은 벌써부터 놀라운 생각을 했다. “만물은 변한다.”라고 일찍이 헤라클레이토스가 말한 것이다. 이 사람들은 “믿음”이라는 것이 관찰자의 시작에 따라 달라진다는, 이른바 상대주의의 관점을 가지고 있었다. 그럼으로써 니체가 태어나기 한참 전에 “도덕”에 대해 다음과 같이 말할 수 있었다.

“도덕적 믿음이 다양하고 보편적이지 않다면, 아마도 모든 도덕은 만들어졌거나, 관습의 문제일 뿐이야” -- 하룻밤의 지식여행 "플라톤"편 중에서

“도덕은 약자가 강자를 구속하여 그 힘을 저지하기 위한 발명이고, 힘은 최고의 덕이며 인간 최고의 욕구야”  -- 윌 듀랜트의 철학이야기 중에서

잘못된 것에 대한 절대적인 믿음도 히틀러를 낳지만, 절대적인 옳음이란 없다는 이것 또한 윤리적 회의주의를 낳을 수 있고, 종국에는 윤리적 허무주의까지 이르게 될 수 있다. 이러한 생각을 가진 소피스트에게 대화란 무엇일까? 세계 최고의 변론술을 자랑했던 그들에게 있어 대화는 무엇을 의미하는가? 절대적인 옮음의 가치가 없는 그들에게 대화란 단지 이 세계에서(그들은 이 세계, 저 세계라는 이분법적 사고도 좋아하지 않을 것이다..) 성공하기 위한 기술이었다. 대화란 그름을 옳은 것으로 둔갑시키거나 옳음을 그름으로 둔갑시키는 기술이었고(양심의 가책을 느낄 필요도 없다, 왜냐면 그들에게 있어 절대적인 옳고 그름이란 존재하지 않기 때문이다),논쟁에서 이겨 이 세계에서 부를 축적하기 위한 도구였다. 소피스트의 경우, 대화란 절대적 옳음이 없는 이 세계에서 승리하기 위한 무기이다.

 

소크라테스의 경우

소크라테스는 소피스트들의 행위를 보았다. 그들의 생각과 행동이 사회를 어그러지게 하는 것을 목격했고, 그는 위기감을 느꼈다. 그들의 생각이 사회에 팽배해지면 그가 사랑하는 아테네는 무너지고 말 것이라 생각했기 때문이었다. 그는 변하고도 물렁한 지대가 아닌 곧고도 단단한 반석 위에 자신의 나라와 세계를 올리고 싶었다. 그가 믿은 그 반석이란 무엇인가? 바로 “진리”이다. 장소와 시간을 뛰어넘은 진리, 그는 그것이 존재한다고 생각했고 또한 간절히 그것을 원했다. 소피스트에게는 승리하기 위한 말장난에 불과한 변증법을 그는 철학의 도구로 사용했다. 상대방을 이기고 넘어뜨리기 위한 수단이 아닌 어두운 곳을 밝혀줄 진리의 안내자로 대화를 사용했다. 이 경우 소크라테스에게 대화란 “진리”에 다가가기 위한 도구이다

 

잠깐 소크라테스의 목소리를 들어본다.

 

그렇고 말고 파이돈, 그런데 진리나 확실성이나 지식의 가능성이 있다고 하면, 사람이 처음에는 옳다고 여겼으나 후에는 거짓임이 밝혀진 어떤 이론에 부딪혔다고 해서 자기 자신과 자기 자신의 지능의 결핍을 탓하지 않고, 괴로운 나머지 결국은 자기 자신이 아니라 이론 전반에 기꺼이 책임을 돌리고, 그 후에는 영원히 이론을 미워하고 욕하고, 실재에 관한 진리와 지식을 상실한다는 것은 얼마나 슬픈일인가?

승리를 좋아하는 사람은 논쟁을 할 떄, 문제가 정당한 것인가 하는 점은 개의치 않고 오직 듣는 사람에게 자기 자신의 주장을 확신시키고자 애를 쓰네. 그는 청중이 그의 말을 옳게 여기도록 애를 쓰는 데 반해 나는 오히려 나 자신을 확신시키려고 노력하고 있네.

나는 자네들에게 진리만을 생각하고, 소크라테스의 일은 생각하지 말라고 요구하겠네. 내가 자네들에게 진리를 말한다고 생각되면 나에게 동의하고 만일 그렇지 않으면 열정 때문에 자네들과 나 자신을 기만하는 일이 없도록, 전력을 기울여 반대해 주게. – 플라톤의 파이돈 중에서

 

 

글 투에 드러났겠지만 난 ‘소크라테스의 경우’ 나타난 대화의 사용을 가장 좋아하게 되었다. 소크라테스가 아닌 다른 2개의 경우 대화의 목적, 그 뿌리로 들어가 보면 “나”라는 원자를 발견할 수 있다. 소크라테스는 그 “나”라는 뿌리를 “진리”로 바꾸어버렸다. 이제 나도 그렇게 하려고 노력하고 있다. 과거 대화 중 나 자신이 충분히 드러나지 않으면 속상해하고 분해 했으나 이제는 그러지 않을 수 있다. 이전에 다른 이의 말의 아름다운 줄기를 보기 보다는 곁가지의 오류만을 보고 그것을 지적했다면, 이제는 진정 귀를 기울여 그들이 진짜로 말하고 싶어하는 ‘본질’을 찾기 위해 노력한다. 다른 이들의 사소해 보이는 작은 오가는 말속에 그들의 인생과 깨달음이 옹기종기 모여있음을 보고, 그들이 발견한 진리에 나도 발을 담그고 싶어한다. 남을 낮은 곳에 두고 내려보는 것이 아니라, 높은 곳에 두고 올려보려고 노력한다. 사소한 모든 것에서 소크라테스가 찾고 있는 진리를 나도 찾을 수 있도록, 온전하고도 사그라지지 않는 그 실재에 나도 다가가고자 애쓰고 있다.


그러므로 시간을 초월한 소크라테스가 아직 내 가슴 안에 이렇게 살아, 나를 움직이고 깨우치고 있다.

 

저작자 표시
신고

WPF Template의 이해

프로그래밍 2010.02.09 19:30 Posted by 아일레프

Template에 대해서 간단히 포스팅 합니다.

 

<Button Height="100" >

            <TextBlock Height="Test"></TextBlock>

</Button>

 

XamlReader는 위 XAML 코드를 아래와 같은 코드로 번역할 것입니다.

 

Button button = new Button { Height = 100 };

button.Content = new TextBlock { Text = "Test"

 

Button과 TextBlock의 실제 Instance를 내부에서 실제로 ‘생성’하게 되는 것이죠. 하지만 Template의 경우는 이와 완전히 다릅니다.

 

<Button Height="100" >

            <Button.ContentTemplate>

                <DataTemplate>

                    <StackPanel Orientation="Horizontal">

                        <TextBlock Text="Content : "/>

                        <ContentControl Content="{Binding }"/>

                    </StackPanel>

                </DataTemplate>

            </Button.ContentTemplate>

            <TextBlock>Test</TextBlock>

</Button>

 

그리고 이 포스트를 더 읽지 마시고, 잠깐 저 XAML을 코드로 나타내면 어떻게 될 지 생각 해봅시다.

 

 

 

혹시 아래와 같다고 생각하셨나요?

               
Button button = new Button { Height = 100 };

DataTemplate template = new DataTemplate();

StackPanel stackPanel = new StackPanel { Orientation = Orientation.Horizontal };

stackPanel.Children.Add(new TextBlock { Text = "Content : " });

stackPanel.Children.Add(new ContentControl { Content = new Binding() });

template.Content = stackPanel;

 

button.ContentTemplate = template;

button.Content = new TextBlock { Text = "Test" };

 

하지만 재미있게도 Template의 경우는 위와 같은 코드로 번역되지 않습니다. 왜냐면 Template – 한국말로 ‘틀’ – 이기 때문입니다. Template의 목적은 하나의 단일 Object Tree를 생성하기 위한 것이 아니라 Object Tree를 만들어내는 ‘틀’을 만드는 것에 있기 때문입니다. 긴말하지 않고 위 XAML이 어떻게 번역되는지 코드로 알려드립니다.

 

Button button = new Button { Height = 100 };

FrameworkElementFactory stackPanelFactory = new FrameworkElementFactory(typeof(StackPanel));

stackPanelFactory.SetValue(StackPanel.OrientationProperty, Orientation.Horizontal);

 

FrameworkElementFactory textBlockFactory = new FrameworkElementFactory(typeof(TextBlock));

textBlockFactory.SetValue(TextBlock.TextProperty, "Content : ");

 

FrameworkElementFactory contentControlFactory = new FrameworkElementFactory(typeof(ContentControl));

textBlockFactory.SetBinding(ContentControl.ContentProperty, new Binding());

 

stackPanelFactory.AppendChild(textBlockFactory);

stackPanelFactory.AppendChild(contentControlFactory);

 

DataTemplate template = new DataTemplate();

 

template.VisualTree = stackPanelFactory;

 

button.ContentTemplate = template;

button.Content = new TextBlock { Text = "Test" };

 

재미있지요? 실제 Object를 생성하는 것이 아니라 FrameworkElementFactory라는 녀석을 사용하고 있습니다. 즉, Template는 이 녀석을 사용해서 자신의 ‘틀’의 모양을 구성하고 이 틀을 사용해서 자신의 틀과 일치하는 Object Tree을 마구 마구 찍어 낼 수 있는 겁니다.

 

//위의 코드에 계속해서..

template.Seal();

object obj1 = template.LoadContent();

object obj2 = template.LoadContent();

 

bool isSame = obj1 == obj2;

 

자, 간단한 퀴즈가 나갑니다. 위 코드가 실행되면 isSame이라는 변수에는 어떤 값이 들어갈까요?




















예 맞습니다. ‘false’가 들어갑니다. LoadContent()라는 메소드가 ‘너의 틀을 이용해서 Object Tree를 찍어내라!’라는 명령을 수행하기 때문입니다. 따라서 ob1과 obj2는 전혀 다른 객체입니다.

저작자 표시
신고

너를 품에 안으면

노래이야기 2010.02.09 17:10 Posted by 아일레프


저작자 표시
신고

그 녀석, 그리고 Creep

노래이야기 2010.01.17 21:53 Posted by 아일레프

우연히 다시 이 노래를 듣게 되었고 난 어김없이 그 녀석을 떠올렸다.


왜, 누구에게든 자신이 도달하고 싶지만 결코 도달할 수 없는 어떤 이상향이 있을 것이다. 어렸을 때, 정확히 내 초등학교 시절에서  고등학교의 시절동안 그 이상향은 머리 속에서만 존재하는 관념이 아니라 단 한 명의 사람으로 이 세계에 명확히 존재하는 실재였다.

녀석은 모든 것에서 대단했다. 놀라운 두뇌를 가져서 항상 훌륭한 성적을 유지하고 있었고 굉장한 리더쉽과 훌륭한 인품을 가지고 있어서 녀석은 모든 이들의 친구였다. 아웃사이더들의 친구였고, 날라리들의 친구였고, 나같은 좆밥들과의 친구이기도 했다. 게다가.. 그 녀석은 '정의'로웠다. 감히 동경하지 않을 수 있겠는가? 하지만 우상과 친구가 될 수는 없는 법이기에 난 결코 그 녀석과 친구일 수가 없었다.

어느날이었다. 내가 이어폰을 끼고 이 노래를 듣고 있었는데 그 녀석이 다가와 무슨 노래를 듣냐고 물었다. 라디오 헤드의 Creep이라고 하자 그 녀석이 반가운 미소와 함께

"나도 그 노래 아는데, 근데 그 노래 가사가 어떤 뜻인지 알아?"

"아니 모르는데"

"내가 말해줄께, 가사를 알고 들으면 더욱 기막힌 노래야"

그리고 그 녀석은 가사를 말해주었다. 그리고 들었다. 그 가사의 내용을 온전히 들었다. 
그리고 그 아이러니한 순간. 내 fuckin special one이 내게 Creep 가사를 가르쳐주고 있다니!!
Oh.. I'm a Creep..



When you were here before,
Couldn't look you in the eye
You're just like an angel,
Your skin makes me cry

You float like a feather
In a beautiful world
And I wish I was special
You're so fucking special

But I'm a creep, I'm a weirdo
What the hell am I doing here?
I don't belong here

I don't care if it hurts,
I want to have control
I want a perfect body,
I want a perfect soul

I want you to notice
When I'm not around
You're so fucking special
I wish I was special

But I'm a creep, I'm a weirdo
What the hell am I doing here?
I don't belong here

She's running out again
She's running out,
she run run run run ...

Whatever makes you happy
Whatever you want
You're so fucking special
I wish I was special

But I'm a creep, I'm a weirdo
What the hell am I doing here?
I don't belong here
I don't belong here.



저작자 표시
신고

우리와는 멀리 떨어진 곳이지만, 아이티에서 지진으로 많은 사람이 죽었다고 합니다.

내게 직접적인 아무런 영향도 없고, 내가 딛고 있는 내 발아래의 이 땅은 너무나도 안전하기에, 여전한 웃음을 품고 하루를 잘도 살아가고 있지만, 그 와중에 예전 리아 에서 인용한 시가 다시 생각나 함께 나눕니다.

 

 

누구를 위하여 종은 울리나

 

어떤 사람도 그 자체로 온전한 섬은 아니다

모든 사람은 대륙의 한 조각, 본토의 일부이다

만일 흙 한 덩이가 바닷물에 씻겨 나가면,

유럽은 그만큼 줄어든다

한 곶이 씻겨 나가도 마찬가지고,

그대의 친구나 그대의 영토가 씻겨 나가도 마찬가지다

어떤 사람의 죽음도 나를 줄어들게 한다

나는 인류 속에 포함되어 있기 때문이다

그러니 누구를 위하여 종은 울리나

알려고 사람을 보내지 말라

그것은 그대를 위하여 울린다

 

 

존 던, 천국으로 가는 시

 

 

시인이며 목사인 존던이 살던 영국 그때, 그리고 그곳에서는 전염병으로 인해 많은 사람들이 죽었다고 합니다. 존 던이 살던 마을에서도 많은 사람들이 죽었는데 한 사람이 전염병으로 숨을 멈출 때 마다 교회의 종을 울리게 했다고 합니다. 존 던은 그 종이 울릴 때마다 이렇게 궁금해 했겠죠. “종이 울렸구나, 누군가가 죽었나보다.” 그런데 어느날 존던 마저 전염병이 걸렸습니다. 그리고 병석에 누워 있던 중 그 종소리를 다시 듣게 되었습니다. 그 때 존던은 느꼈던것입니다. 저 종의 울림이 바로 자신을 위한 것 이었음을. 그리고 저 위대한 시를 짓게 되었습니다.

 

그날 아이티에서 매우 커다란 종이 울렸습니다. 우리 또한 대륙속에 한 모래이기에, 우리는 인류속에 포함되어있기 때문에,  그 종소리는 우리들을 위한 종소리입니다.

 

잠깐 눈을 감고 기도해봅니다.

저작자 표시
신고

Blue Eyes Blue- Eric Clapton

노래이야기 2009.12.31 09:51 Posted by 아일레프



"It was you, it was you who made my blue eyes blue."
최근에 본 것 중 가장 아름다운 영어 문장이다. 
나는 검은 눈을 가졌기에 이 아름다운 가사를 누군가에게 써먹을 수 없다는 것이 안타깝다.


I thought that you'd be loving me.

I thought you were the one who'd stay forever.
But now forever's come and gone
And I'm still here alone.

'Cause you were only playing,
You were only playing with my heart.
I was never waiting,
I was never waiting for the tears to start.

It was you who put the clouds around me.
It was you who made the tears fall down.
It was you who broke my heart in pieces.
It was you, it was you who made my blue eyes blue.
Oh, I never should have trusted you.

I thought that I'd be all you need.
In your eyes I thought I saw my heaven.
And now my heaven's gone away
And I'm out in the cold.

'Cause you had me believing,
You had me believing in a lie.
Guess I couldn't see it,
I guess I couldn't see it till I saw goodbye.

Chorus

'Cause you were only playing,
You were only playing with my heart.
I was never waiting,
I was never waiting for the tears to start.

It was you who put the clouds around me.
It was you.

It was you who put those clouds around me.
It was you who made those tears fall down.
Only you who broke my heart in pieces.
It was you, it was you who made my blue eyes blue.
Oh, I never should have trusted you.

Oh, I never should have trusted you.
Oh, I never should have trusted you.
Oh, I never should have trusted you.


저작자 표시
신고

마음 - 10점나쓰메 소세키 지음, 오유리 옮김/문예출판사

B – 이게 끝이 아니라니?

A – 이봐, 사람은, 아니 나란 사람은 죄책감을 가지고서는 더 이상 가슴을 펴고, 얼굴에 웃음을 가진 채 결코 살 수 없는 거야. 결국 그것을 극복하거나 버려야하네. 그 간극에서 나는 여러 가지를 시도해보았던 것 같아. ‘보았네’라는 말로 표현하지 않고 ‘같아’라고 말한 것은 내가 그 때에는 나의 머릿속에서 복잡하게 돌아가는 어떠한 현상 자체를 완전히 몰랐기 때문이야. 지금 그 사실에 대해서 말할 수 있는 것은 이 책이 내가 했던 행동들과 내가 한 선택을 일깨워 주었기 때문이고.

B – 그래, 그게 무엇이란 말인가?

A – … 말하겠네. 기독교를 믿는 나는 마치 내가 그녀를 지옥에 버려두고 온 것처럼 느껴졌었네. 그리고 나는 그녀를 그 지옥에서 이 곳으로 다시 데려올 수도 있었고, 그냥 둘 수도 있었네. 그런데 내 머리 속에서 명확한 사실이 내게 말을 걸었다네. ‘이곳으로 데려오는 것은 완전히 불가능’하다고. 결국 나는 그냥 두는 쪽을 선택해야만 했어. 그런데 또 갈림길에서 서 있었지. 하나는 내가 명백하게 그 사실, 내가 그녀를 버려둔 채 왔다는 사실을 인지하고서 ‘마음’의 선생처럼 살 것인지, 아니면 그 사실로부터 완전히 도피 할 것인지 선택 해야 하는 그 길목이었어.

B – 거기서 도피하는 길을 선택했다는 것인가?

A – 그래, 그런데 지금 와서 소름 끼치는 것은, 내가 거기서 도피했다는 그 사실 때문이 아니야.

B – 젠장, 그럼 뭐란 말인가?

A – 화내지 말게나, 내가 소름 끼쳤던 것은, 도피했다는 그 자체가 아니라 도피하기 위해 내 머리 속에서 저절로 동작한 그 어떤 것 이었어. 난 결코 쉽게 도피할 수 없었기 때문에 다른 길을 택해야 했던 거야.

B – 그래 그게 뭐냐고.

A – 그것은, 내가 어느 순간 ‘만인 구원설’이란 것을 믿기 시작했다는 사실이야. 믿기 시작했던 것 뿐만 아니라 다른 사람들에게 알리기도 했다네. 이런 저런 이유를 들어가면서. 난 그게 옳은 결론인 줄로만 알았어. 그런데, 그게 아니었던 거야. 난 그것 – 하나님이 믿는 자와 불신자를 모두 구원해 준다는 설–을 믿음으로써 그제서야 그 ‘죄책감’ 으로부터 도피할 수 있었던 것이지. 그 돌파구를 찾은 후에야 난 다시 웃을 수 있었고, 내 삶에는 다시 행복이라는 글귀가 써지기 시작했네.

B – 별 시덥잖은 얘기를 하고 있구만. 그런데 그게 도대체 이 책과 무슨 관련이 있다는 것인가?

A – 내가 말하고자 하는 것을 정말 모르겠나? 사람이란 그런거야. 자신 안에 숨어있는 죄책을 버리기 위해서 지금까지 가져온, 마음 한구석에 가장 높고도 중요한 위치에 올려놓은 그 믿음과 신념을 다른 것으로 변형할 수도 있다는 것이 바로 사람이라는 것이네. 30년이 넘게 그 죄책을 가지고 있는다는 것이 쉽지 않다는 것을 말하고 싶었던 것이네. 당신은 그 선생이 ‘자기애’로 똘똘 뭉쳐진 사람이라고 했지만 자기애로 뭉쳐진 사람은 그런 짓을 하지 못해. 죄책이라는 것을 가슴에 두고 살 수 없다고.

B – 그렇군. 자네가 왜 감동을 느꼈는지 알겠어. 하지만 말이야, 그 죄책이라는 것을 버린다는 것과 그것으로부터 도망친다는 것이 과연 잘못된 것일까? 이렇게 생각해보게. 사람은 삶을 살아야해. 그 삶을 영위해야만 한다고. 남들을 용서해야 하고, 자신을 용서해야하고, 남들을 사랑해야하고, 자신을 사랑해야하네. 어쨌던 간에 살아가야 한다는 거야. 이봐, 그 선생이 마지막에 취한 행동을 생각해봐 죄책을 가슴에 꽁꽁 숨겨두고 30여년을 지내온 그 과정과, 그 결과가 무엇이었냐고? 그 사람은 살아간 적이 없어. 세월을 좀먹고 있었을 뿐이야. 결국에는 결말이 어땠는가? 마누라를 홀로 두고 자살하는 것 밖에 없지 않았나? 그것은 찌질이의 인생이야.

A – 부탁인데, 찌질이라고 말하지 말게나.

B – 이 사람, 너무 몰입했구만. 그렇게 얼굴을 붉히지 말게.

A – 좋아, 그렇다면 쿨하다는 것은 무엇인가? 자신이 살아온 뒷길에 난 그 발자국을 쉽게 잊어버리고, 내일을 위해서만 터벅 터벅 걷고, 빠르게 뛰어가는 그것이 쿨하다는 것인가? 이봐 우리네 삶은 중요한 것을 몰라. 너무 빨리 깨닫고, 너무 빨리 움직이고, 그리고 너무 빠르게 배우고 있어. 너무 빠르게 용서하고 있고, 너무 빠르게 사랑하고, 금새 회복하지. 그것이 쿨하다는 것의 가치인가? 우리는 놓치고 있어. 살아가기위해서, 아니 좀더 효율성있게 살아가기 위해서 아름답고 곱씹어야 할 인생길의 아름다운 풍경들을 놓쳐버리고 있다고. 이봐, 내 삶에 후회되는 것 중 몇 가지 중 하나가 뭔지 아는가?

B – 무엇인가?

A – 고등학교때 빠르게 언어영역 성적을 올리기 위해서 그 커다란 윤동주 시의 감동을 ‘정답’으로 외웠다는 것이네. 우리 삶도 그와 다르지 않아. 그 선생을 그려놓은 그 소설이 가치가 있고 아름답다면 거기에는 그런 아름다움이 있기 때문이야. 우리들이 말하는 그 정답대로 살지 않은 사람의 아름다움이 거기에 있었어.

B – 재미있군. 그러나 자네는 그렇게 살 수 있는가? 자네가 생각하는 그 ‘쿨’함의 가치를 벗어던지고 살 수있겠나? 아니, 내가 아는 자네는 그렇지 않아.

A – 나도 알아.

B – 그래. 나도 자네가 그것을 알고 있을 것 같았어. 그렇다면 굳이 과거의 죄책을 끄집어 내서 그것과 다시 씨름하지 말게나. 그것을 끄집어 낸다고 해도 자네가 할 수 있는 최선의 것은 이렇게 나 같은 사람과 얘기하는 것 뿐이지 않은가? 그렇다면 절대 나오지 않도록 숨겨버리게. 그게 아니라면 이런 식으로 꺼내서 다른 사람에게 그것을 말하지도 말게. 말하는 순간 자네의 죄책은 더 이상 죄책이 아니라 단지 유희에 불과하기 때문이야. 자네의 죄책을 숨기는 것보다 꺼낸 후에 이런 식으로 모독하는 것이 더 나빠.

A – 대단하군. 언제부터 이렇게 가슴을 찌르는 말을 할 수 있었나?

B – 그걸 모르나? 바로 자네한테 배웠다네. 하여간 책은 잘 봤어.

A – … 그래. 다행이야.

B – 다행이고 말고.



 
저작자 표시
신고

마음 - 10점나쓰메 소세키 지음, 오유리 옮김/문예출판사

A – 다 읽었나?

B – 다 읽어 보았다네. 자네가 하도 읽어 보라고 권하길래.

A – 어떻던가?

B – 글쎄… 음… 그냥 그런 느낌이 들었어. 자네는 내가 이 책을 읽고 그렇게 기분이 좋아지지 않을 거란 사실을 알고 있을 것 같다는… 그런 막연한 느낌 말이야.

A – 하하, 재미있군. 사실 자네 말이 맞아. 어느 정도는 알고 있었지. 내가 아는 소설의 그 선생과 가장 다른 사람이 바로 자네였거든. 그래서 없는 친구들 가운데에서 자네를 선택했지.

B – 그렇군, 그렇다면 자네하고 나하고 가장 극단에 있는 사람이니, 자네는 그 선생의 분신쯤 되겠어. 물론 자살할만한 이유도, 용기도 없어보이지만 말이야.

A – 그것도 어느 정도 정확하네. 사실 나와 닮았다기 보다는 내가 닮고 싶지만 결코 닿을 수 없는 어디 즈음에 그 선생과 K가 있었어.

B – 재미있군, K는 그나마 괜찮은데 그 찌질이 선생을 닮고 싶었다는 건가?

A – 찌질하다니, 그 말은 좀 심했네.

B – 찌질하고 말고, 난 내 주위에 그런 녀석이 있으면 한대 패주고 말꺼야. 장난치는 것도 아니고. 난 그녀석이 진실로 죄책감에 시달렸는지 그것도 의문이 들어. 내가 봤을 때 그건 죄책감이 아니야. 내가 본 그 선생은 자기애로만 가득 차있는 사람이야. 그런 사람은 남을 사랑할 줄도, 용서할 줄도, 그리고 용서 받는 방법도 몰라. 근본적으로 자기밖에 모르는 녀석이야. 혹시나 그런 사람하고 상종하지 말게나, 당신 인생이 피곤해져.

A – 이 친구 재미있구만. 나와 그 선생과 닮은 셈이니, 자네는 나와 상종하지 말아야겠군.

B – 하하, 그렇게 되는 건가? 하여간 재미있어.

A – 좀 더 계속해보게, 왜 그 선생을 그렇게 생각하나?

B – 이 친구도 참 이상하군. 자네는 은근히 마조히스트적인 측면이 있어. 자네와 비슷한 사람을 욕하는 걸 듣고 싶단 말인가?

A – 그래, 듣고 싶어.

B – 재미있군. 소설의 작가가 그렇게 의도했는지 모르겠지만 녀석은 그야말로 최악이야. 내 생각에 그 녀석은 자신이 그 때 그 일로 고통받고 있다는 것을 어느 정도 즐겼다는 느낌이 들어.

A – 계속해보게.

B – 왜냐면, 그런 종류의 사람에게 자신의 존재를 증명하는 방법이 바로 그것이기 때문이야. 과거의 그 일 때문에 행복하지 못함으로써, 충분히 참회하고 있다고 생각하겠지. 모르긴 몰라도, 자신이 그 죄책감으로 아파할 때마다, 현실과 떨어져 있는 자신을 볼 때 마다 한편으로는 자신이 자랑스러웠을 지도 몰라. 왜, 그런것 있잖아, 도덕을 철저히 지키고, 금욕을 함으로써 누리는 은근한 즐거움 말이야.

A – 하지만 그렇지는 않은 것 같아. 너무 비약이야. 선생은 K의 그 일을 통해 자신이 증오하고 멸시했던 사람들과 자신이 별 차이가 없다고 느꼈잖아. 그것에 대해 환멸을 느끼고 좌절했다고 하고. 그런데 그것을 느낌으로써 즐거워했다는 것은 말이 안돼.

B – 아니, 그렇지 않아. 자네 방금 좋은 이야기를 해줬네. 자네의 말이 오히려 힌트가 되었어. 선생이 괴로워했던 것은 K의 죽음과 그의 부재가 아니야. K가 죽음으로 인해 마침내 마주하게된 자신의 더러움이지. 자신은 괜찮은 사람이라고 생각했는데 알고보니 남들과 다를 바가 없었던거야. 그거 때문에 괴로워한거지.

A – 꼭 그렇다고 보기는 어려울 것 같아. 소세키가 소설에서 뽑아낸 가장 아름다운 장면 중 하나는 K의 죽음에 슬퍼하는 그 선생의 심리 묘사야. 거기에는 슬픔말고 다른 그 어떤 요소도 없어.

B – 나도 그것에는 동일하네. 그 때 그의 마음에는 슬픔밖에 없었겠지. 하지만 그 이후는 아니라고 본다네. 그를 움직이고 그의 죄책감을 살찌우게 했던 그것은 근본적으로 비겁한 자기애라고 난 생각하네.

A – 어떻게 정상참작이 안되겠나?

B – 하하, 안되지. 안되고 말고. 이런 인간은 정상참작이 안되는 인간이야. 아, 맞아 이 책을 읽으면서 또 다른 생각이 들었네. 선생의 자살에 대해서 말이야. 왜 그 선생은 자살이란 방법도 스스로 생각 못했잖아? 결국에는 노기 대장이 자살했다는 뉴스를 보고 아, 저런 방법도 있구나라고 생각한 것이고.

A – 그렇지. 그건 사실이니까.

B – 그런데 난 노기 대장이 자살했다는 것말고 그의 자살에 다른 중요한 도움이 되는 요소가 있다고 생각하네.

A – 그게 뭔데?

B – 그건 바로 제자야. 그 제자가 없었다면, 자신의 생각과 괴로웠던 그 일들을 들어줄 그 누군가가 없었더라면, 자신의 그 괴로움과 절망의 기나긴 스토리를 편지로 읽어줄 누군가가 없었더라면 그가 과연 자살을 했을까? 난 아니라고 보네.

A – 그것은 비약을 넘어선 억지야. 선생은 그 이야기를 무덤까지 가져가려고 했어. 제자가 조르지 않았더라면, 소세키의 표현대로 하자면, 선생의 심장을 도려내 기꺼이 그 피를 마시고자 하는 열의를 그 선생이 발견하지 못했더라면 그 편지로 그 이야기를 쓰지 않았을 것이네.

B – 음… 그래.. 그건 동의하네. 여하튼 내 느낌은 그래. 자네는 어떤가? 왜 이딴 인간이 닮고 싶다는거야?

A – 몇가지 측면이 있는데, 일단 그가 자신의 죄에 대해서 깊숙하고 오랫동안 반응해 왔다는 사실이야.

B – 그게 아니라고 말했잖아, 그건 비겁한 자기애에 불과하다고.

A – 아니야. 그렇지 않아, 내가 생각하는 사람이란 그렇게 오랫동안 죄에 대한 분명한 인식을 가지고서는 살수가 없어. 하지만 그는 그렇게 살았다는 거야. 남들은 자기애라고 애둘려서 말하지만, 난 그럴수가 없어.

B – 음..

A – 사실 이 이야기를 해야겠네. 마음속에 감추고 있었는데 이 소설이 다시 그것을 끄집어냈어. 숨기려고 했는데 이 이야기를 하지 않고서는 중요한 메시지를 전할 수 없을 것 같아.

B – 뭔데, 말해보게.

A – 자네, 내가 기독교 신자라는 것 잘 알고 있지?

B – 그래. 잘 알고있지.

A – 그래, 알고 있겠지만 기독교에서 구원이란 인간의 행동에서 오는 것이 아니라고 설명하고 있어. 구원이란 예수 그리스도의 십자가의 대속의 역사를 믿는 믿음 바로 그것을 통해 온다고 말하고 있는거지.

B – 그래, 정말 어처구니 없지만 그것도 알고 있어.

A – 자네는 내 옛 여자친구를 알고 있지? 이제 말하는 거지만 그녀는 불교 신자였어. 하지만 독실하지는 않은 그런 신자였어. 그리고 이보게, 난 참말로 제대로 믿지도 않는 사실을 남들에게 강요하기는 좋아하는 그런 신자였어.

B – 응? 난 자네에게 그런 면은 전혀 느끼지 못했는데?

A – 그래 아마 그랬을 거야. 나도 그렇지 않았다고 생각하거든. 그래서 여자친구가 불교신자라는 사실에도 아무 꺼리낌이 없었네. 하지만 여자친구에게는 달랐지. 나도 모르게 나만의 도덕과 율법을 그리스도의 이름으로 그녀에게 강요했어. 자네가 말했듯이 거기에는 사랑이 없었네. 그냥 자기애만 있을 뿐이었어.

B – 헤어진 것이 그것 때문인가?

A – 아니, 그런것은 아니야. 종교의 문제로 헤어지지는 않았어. 다만 중요한 것은 그녀가 헤어질 때 이렇게 말했다는 사실이야. “나는 이제 절대 기독교인과 상종하지 않을꺼야” 라고.

B – 자네가 정말로 지긋지긋 했나보군. 잘좀 하지 그랬나.

A – 그래, 아마 그럴수도. 그런데 그게 심각한 문제였어. 헤어졌다는 사실보다도 그녀가 한 마지막 말이 내 가슴을 찌르고 찔렀지. 만약 그녀가 그 말을 조금 더 불편한 얼굴로 했다면 난 아마 견디기 힘들었을 것이네. 헤어졌다는 사실보다 그 말이 더 가슴아팠어. 왜냐면 기독교에서 구원이란 행동에서 오는 것이 아니라 예수 그리스도를 믿는 믿음 거기서 온다는 사실 때문이야.

B – 응? 좀더 말해보게

A – 그래. 기독교의 교리상 그녀가 만약 예수 그리스도를 죽는 날 까지 믿지 않는다면 그녀는 아마 지옥에 가겠지?

B – 그 말이 맞다면 그렇겠지. 아, 알겠네 자네가 말하는 괴로움이라는 것을.

A – 그래. 나는 한 사람을 구원할 수도 있었어. 아니, 구원하지 않더라도 구원에 대한 열린 기회를 빼앗지 않을 수도 있었는데 내가 그 기회를 빼앗았던 거야. 다름아닌 나의 미숙함 때문에.

B – 자네 성격에 조금 괴로웠겠어.

A – 그래. 많이 슬펐지. 하지만 근본적으로 그녀만을 위해 슬펐던 것은 아닌 것 같아. 다른 치사한 마음도 있었어.

B – 그건 뭔가?

A – 미안하네… 그건 차마 말하지 못하겠어. 하지만 자네 머리로 추리할 수도 있을 것 같으니 스스로 답을 내리기 바래. 다만 날 혐오하지는 말게나.

B – 이미 혐오할 만큼 해서 괜찮아. 말해보게

A -- … 미안하네 차마 말하지 못하겠어. 하지만 이게 끝이 아니야.

 


저작자 표시
신고

관습 어떤 사회에서 오랫동안 지켜 내려와 그 사회 성원들이 널리 인정하는 질서나 풍습

Convention - the way in which sth is done that most people in a society expect and consider to be polite or the right way to do it

 

사람들은 흔히 어떤 사안이 의심할 여지없이 확실하다면 그 문제에 대해 더 이상 생각하지 않으려 하는데, 이것이야 말로 치명적인 악습이 아닐 수 없다. 왜냐하면 사람들이 저지르는 실수의 절반은 그런 버릇에서 비롯되기 때문이다. 우리 시대의 어떤 작가는 확정된 결론은 깊은 잠에 빠진다.고 말했다.” -- J.S.밀의 자유론 중에서

 

지난 주에 읽은 저 책의 내용을 보면서 밑줄을 그으며 끄덕거렸습니다. 충분히 공감했다는 뜻이겠지요. 그리고 나 자신이 아닌 다른 사람들을 떠올렸습니다. —그러고 보면 사람이란 참 우습습니다.— 나에게는 대입되지 않는 다는 자신감으로 저 교훈을 쉽게 잊어버릴 뻔 했었는데 저 글귀를 기억할 만한 일화가 생겨서 공유합니다.

 

잠깐 그 일화를 공개하기 전에 군대에서 있었던, 너무 비 합리적이라 생각할 때마다 웃음이 나오는 에피소드를 말씀 드립니다. 저는 해경 출신인데 축구를 할 수 있는 공간이 해경 부두 밖에 없었습니다. 따라서 축구를 하다가 공이 바다로 가면 영영 잊어버릴 수 있습니다. 따라서 공이 빠지지 않게 공이 나가면 빨리 뛰어서 공을 가져 와야 합니다. 그런데 공이 나갈 때마다 막내 이경이 10명이면 10명 전부 뛰어 나갔습니다. 그 광경이란 지금 상상해도 웃음이 납니다. 저 멀리서 수경이 미친 놈들아! 멍청한 놈들아! 한 명만 가면 되잖아! 한 명만 가라고!” 계속 말합니다. 하지만 멈출 수 없습니다. 공이 누군가의 손에 들리기 전에는 무조건 뛰어야 합니다. – 동기 중 한 명이 이것을 어겼다가 일경에게 맞았습니다군대에서만 볼 수 있는 이런 일이 굉장히 희극적인 이유는 지키는 사람도, 지키라고 하는 사람도 모두 그 관습이 불합리하고 옳지 않다는 것을 너무 잘 알고 있지만 아주 열심히, 온 맘과 정성을 다해 그 관습을 지킨다는 것과, 당한 사람이 고참이 되면 그 관습의 열혈한 수호자가 된다는 사실입니다. 굉장히 재미있는 일이지요.

이 일화는 그냥 웃음을 드리려고 쓴 이야기이고 -- 재미있었나요? -- 진짜 하고 싶은 이야기와는 멀리 동떨어질 수 있습니다. – 군대의 이야기를 현실의 예로 들기에는 그곳이 너무 멀리 있습니다. –

 

최근의 재미있는 일은 이겁니다. WPF 프로그래밍을 하던 동료 중 한 명이 첨부 프로퍼티만을 선언하는 객체는 굳이 DependencyObject를 상속받지 않아도 괜찮지 않냐고 물었습니다. 아무 생각 없이에이, 그럴리가~ 무조건 DependencyObject를 상속해야 될 것 같은데라고 말했습니다. 그 동안 그렇게 써왔기 때문에 바로 그 말이 튀어나오더군요. 그런데 잠시 생각해보니, 그의 말이 옳다라는 사실을 알게 되었습니다. 의존 프로퍼티를 소유하는 객체가 반드시 DependencyObject를 상속해야 하는 것은 맞습니다. 왜냐면 의존 프로퍼티의 Value 결정(상속, 스타일링, 바인딩과 연동하여)을 최종적으로 담당하고 진정한 의존 프로퍼티에 해당하는 Value의 소유권을 주장할 수 있는 것은 DependencyObject만 할 수 있는 것이기 때문입니다.(SetValue, GetValue를 생각하면 됩니다.) 하지만 첨부 프로퍼티는 그 Value의 소유를 자신이 아닌 다른 DependencyObject 객체에 위임하기 때문에 첨부 프로퍼티만을 선언하는 객체는 의존 프로퍼티의 Value의 소유권을 주장할 필요가 없습니다. 따라서 DependencyObject를 상속받지 않아도 잘 동작하게 되는 것입니다.

 

이와 같은 일종의 깨달음을 얻을 수 있었던 것은 그 동료가 당연하게 받아들여지던 무언가에 대해 과감히 질문했기 때문입니다. 그런 질문의 힘은 과연 위대합니다. “왜 그럴까?, 정말 그래야만 하나?”라는 질문은 진실로 진실에 다가가게 해주며 그로 인해 대상의 본질에 대해 더욱 깊이 이해할 수 있게 만들어 줍니다. 그러나 그런 질문을 던지는 것만으로 끝나는 것은 염세주의자의 냉소만큼의 가치만을 지닐 뿐이겠지요. 질문을 했으면 탐구와 실험을 통해서 결론을 내고 그 결론을 다른 이와 공유할 수 있는 용기와 풍요로운 마음을 가져야하는 것입니다.

 

하지만효용효율이라는 가치가 우리 삶에서 점점 더 높은 위치를 차지함에 따라 이런 것에 대해 질문을 스스로 던지고 직접 확인해 보는 것은 멍청한 일처럼 보입니다. 확실해 보이는 특정 정보에 대해서 질문을 던지기 보다는 자신이 모르는, 하지만 남들 모두 알고 있는 것 같아 보이는 다른 정보에 대해 하나 더 아는 것이 안전하고 효율적이며, 궁극적으로 그것이 나에게 더 큰 이득을 가져다 줄 것이란 생각이 자연스레 들기 때문입니다. 결국 더 많은 지식의 축적을 위해, 효율을 위해 사람들은 기존의 암묵적인 옳음에 대해서 더 이상 질문하지 않습니다. 단지 권위 있는 타인에게 의지하므로 스스로 깨우칠 수 있는 권리와 자유로부터 끊임없이 도피하는 것이지요. 결국에는 삶의 가장 중요한 부분마저 다른 사람들이 암묵적으로 합의하고 있는 기준에 자신을 검열하고 맞춰 가게 되는 것입니다.

 

그래도 삶을 살아가는 것에 있어서 빠르게 정보를 익히고, 모난 돌이 되지 않기 위해 스스로를 둥글게 하고, 모든 사람이 공유하는 가치에 대해 공감하고, 그리고 그에 맞는 사람이 되고자 노력하는 것은 사회에서 자신도 모르게 합의한 성공과 행복에 대한 소중한 발판이 될 수 있습니다. 그러나, 개발자로 살아가면서 모든 것을 Yes로 받아들인다면, 그것은비극을 알리는 신호탄이 될 수 있습니다. 아시다시피 개발자로서 다가가는 장벽은 그렇게 높지 않습니다. 미분이 필요한 것도 아니고 적분이 필요한 것도 아닙니다. 약간의 논리적인 생각과 가벼운 덧셈과 뺄셈만 하면 누구나 어느 정도의 성취를 이루어 낼 수 있습니다. 그렇다면 차이를 만드는 것은 무엇일까요? 저는 그것이 새로운 것을 이끌어 낼 수 있는 어떠한 능력에 있다고 생각합니다. 이런 능력을 가지고 있는 사람들을 보면 부러운 마음이 절로 들게 되는 것입니다. 그러나 저 능력이 없다고 자책할 필요는 없습니다. 하지만 적어도 아무런 질문 없이 남의 생각을 그대로 받아들이는 것 만으로 만족하지는 말아야 하겠습니다. 적어도 그 생각이 어디서부터 출발했으며, 이루고자 하는 목표는 무엇이며 그 생각이 어떻게 이용할 수 있을지를 스스로에게 계속 질문해 봐야 하겠습니다. 개발자에게 있어서 자고로 코드의 Copy & Paste보다 무서운 것은 무조건 적인 생각의 Copy & Paste인 것입니다.

 

그러므로 질문하기를 주저하지 맙시다. 그것을 시작으로 해서 효용과 효율이란 가치를 우두머리로 삼아 권위라는 공포와 무관심으로 살찌워진 게으름으로 자신도 모르게 행하는 생각의 Copy & Paste를 이제는 멈추고, 진실에 다가가고 싶은 열망으로 시작되고 열린 대화와 진정한 토론으로 움직이므로 능히 과거를 넘어서고도 남을 수 있는 더욱 더 멋진 일들을 이루어 가도록 합시다.

부디 여러분도 K가 되어 다른 이를 깨우쳐 주시기 바랍니다.

저작자 표시
신고

Code Contract -2

프로그래밍 2009.12.14 18:33 Posted by 아일레프

이전 포스팅(Beyond the Assertion, Code Contract -1)에서 Assertion Assertion으로서의 쓰임과 ‘계약’으로써 사용되는 Assertion에 대해 알아보고 그 한계에 대해 언급한적이 있습니다. 그 한계란 다음과 같았습니다.

1.     Assertion 또는 if-then throw exception을 계약의 목적으로 사용했을 때, 그 계약이 존재한다는 사실은 Runtime에 그 계약을 어겼을 때에만 확실히 알 수있다.

2.     PreCondition, PostCondition, Class Invariants 각각의 계약의 특성에 따른 고유의 특성이 필요하다.

3.     코드 중복

4.     Interface에 계약을 명시할 수 없다.

5.     상위 Type의 계약이 하위 Type에 상속되지 않을 수도 있다.

6.     컴파일시 바이너리에 포함할지 결정하는 조건을 다양하게 하고 싶다.

이번 포스팅에서는 2번에 대해서 알아보기로 합니다. 여러분은 이 포스팅으로 Code Contract를 사용해 PreCondition, PostCondition, Object Invariants를 지정할 수 있을 겁니다.

각 계약의 특성과 Code Contract기본 메소드들

n  PreCondition

메소드의 PreCondition을 만족하는지 체크하게 되고 대부분 Argument 확인을 위해 사용됩니다. 따라서 이것은 Callee를 위해 Caller가 메소드를 올바르게 사용했는지 확인하는 절차가 됩니다. 이러한 목적으로 사용되는 메소드가 Contract 클래스의 Require 메소드입니다.

public static class Contract

{

            [Conditional("CONTRACTS_FULL")]

           public static void Requires(bool condition);

           public static void Requires<TException>(bool condition) where TException : Exception;

}

Contract.Requires는 “CONTRACTS_FULL” 심볼이 Define되어있을 때만 바이너리에 추가되며, Requires<TException> Debug, Release 모두 빌드에 추가되게 됩니다. CONTRACTS_FULL심볼이 Define되어있을 때 PreCondition을 만족하지 못하면 RuntimeContractException이 발생되며 심볼과 관계없이 Requires<TException>을 만족시키지 못하면 Runtime TException을 발생시키게 됩니다.

Requires PreCondition의 특성에 따라 메소드의 시작부분 또는 변수 선언 바로 다음에만 사용할 수 있습니다. 그렇지 않으면 빌드에러가 발생합니다.

private int Factorial(int number)

{

      Contract.Requires<ArgumentException>(number >= 0);

}

 

n  PostCondition

PreCondition Caller가 메소드를 올바르게 사용했는지 확인하는 절차라면 PostCondition Caller를 위해 Callee 메소드가 계약에 맞게 수행되었는 지 확인하는 절차입니다. 이러한 목적으로 사용되는 것이 Contract클래스의 Ensures메소드입니다.

public static class Contract

{

           [Conditional("CONTRACTS_FULL")]

           public static void Ensures(bool condition);

           [Conditional("CONTRACTS_FULL")]

           public static void EnsuresOnThrow<TException>(bool condition) where TException : Exception;

}

Ensures EnsuresOnThrow모두 CONTRACTS_FULL심볼이 정의 되어있을 때만 바이너리에 포함되게 됩니다. 이것이 PreCondition PostCondition과의 중요한 차이점 입니다. Requires는 배포시에도 필요성이 있지만 – 사용자에게 잘못된 메소드 사용이라는 것을 알려주기 위해 – PostCondition의 경우는 그렇지 않기 때문입니다.

또한 PostCondition는 그 쓰임에 있어서 별도의 Helper 메소드를 필요로 합니다. 예를 들어 Factorial(number)를 호출했다고 했을 때 반환되는 값은 반드시 argument number’보다 같거나 커야합니다. 이를 어떻게 확인할 수 있을까요? 먼저 argument number가 메소드의 body에 의해서 변할 수 있으니 number를 다른 변수에 저장해 놓아야 할 것입니다. 또한 이 값과 return값을 비교해야 하기 때문에 별도의 returnResult 변수가 필요로 합니다. 코드로 다시 설명하겠습니다. 만약 이 PostCondition을 검사하지 않는 다면 Factorial메소드는 다음과 같을 것입니다.

private int Factorial(int number)

{

           Contract.Requires<ArgumentException>(number >= 0);

           if (number == 1 || number == 0) return 1;

           return number * Factorial(number - 1);

}

이 경우 PostCondition을 확인하기 위해 다음과 같은 메소드가 되어야 합니다.

private int Factorial(int number)

{

           Contract.Requires<ArgumentException>(number >= 0);

        if (number == 1 || number == 0) return 1;

        int result = number * Factorial(number - 1);

        Contract.Ensures(result >= number);

        return result;

}

그 결과 불필요한 result라는 변수가 추가되었습니다. 게다가 기존의 코드를 해치는 SideEffect가 발생했습니다. 당신이 PM이라면 당신의 사랑스러운 개발자들에게 이 일을 하라고 말할 수 있겠습니까? 어떻게 기존의 코드를 수정하지 않고 이 일을 할 수 있는 방법이 없을까요? 있습니다. -- 저는 Code Contract에서 이 기능을 가장 사랑합니다. Contract클래스의 몇가지 Helper메소드를 이용해 위와 똑같은 기능을 하는 코드를 다음과 같이 작성할 수 있습니다.

private int Factorial(int number)

{

Contract.Requires<ArgumentException>(number >= 0);

Contract.Ensures(Contract.Result<int>() > Contract.OldValue(number));

       if (number == 1 || number == 0) return 1;

       return number * Factorial(number - 1);

}

Contract.Ensures(Contract.Result<int>() > Contract.OldValue(number)); 의 의미는 이것입니다. 이 메소드의 결과값은 PreCondition state이었을 때의 number값보다 커야한다 OK, 이걸로 Contract.ResultContract.OldValue의 역할을 유추하실 수 있으실겁니다. Contract.Result<T>() return되는 결과값을 의미하는 것이고 Contract.OldValue<T>(T value) PreCondition state였을 때의 value값을 의미하는 것입니다. 그런데 아무리 그렇다고 하더라도 이 코드에는 의문점이 많이 있습니다. 아니 결과 값은 저 코드 뒤에 나오는데 어떻게 이것이 가능하단 말입니까? 여러분은 이것이 단 한가지 방법으로만 가능하다고 추측하실 수 있을 겁니다. , 맞습니다. Code Contract는 빌드 후에 IL코드를 수정하게 됩니다. 이것을 Code Contract Binary Rewriter라고 부르더군요. 이에 대해서는 나중에 자세히 알아보기로 합니다.

 

n  Class Invariants

Class Invariants 또는 Object Invariants라고 불리는 이 Condition은 모든 Public 메소드가 불린 후에 반드시 만족해야 하는 클래스의 조건입니다. 사실 이것은 모든 public 메소드에 동일한 Contract.Ensures메소드를 추가하는 것으로 이 기능을 만족할 수 있습니다. 그러나 이것 역시 귀찮고 힘든 일이지요. 이와 동일한 일을 Code Contract를 사용해 다음과 같이 할 수 있습니다.

[ContractInvariantMethod]

protected void ObjectInvariant()

{

Contract.Invariant(this.x >= 0);

Contract.Invariant(this.y >= 0);

}

위와 같은 코드를 특정 클래스에 사용하면 CONTRACT_FULL 심볼이 정의되어있을 때 Code Contract [ContractInvariantMethod] 애트리뷰트가 있는 메소드 내의 동작을 모든 public 메소드 뒤에 붙혀버립니다. 그리고 만약 이 Class Invariant를 만족하지 못하면 ContractException을 발생시킵니다.

이번 포스팅에서 가장 PreCondition, PostCondition, Class Invariant를 검사하기 위한 Code Contract의 기본 메소드들을 살펴보았습니다. 다음 포스팅에서는 Interface Contract, Contract 상속 그리고 그 이외의 주제들에 대해 말씀 드리겠습니다.

 

 

신고

Beyond the Assertion, Code Contract -1

프로그래밍 2009.12.09 19:30 Posted by 아일레프

블로그에 따로 포스팅 하지 않았지만 사실 이번에 안재우 과 함께 PDC09에 직접 참석하는 영광을 누렸습니다. 앞으로 PDC09에 참여했던 세션 중 인상 깊었던 것 들에 대해 개인적으로 리뷰할 계획입니다. 이 포스팅은 그 첫번째 입니다.

 

첫날의 마지막 세션이었던 Code Contracts and Pex : Power Charge Your Assertions and UnitTests 에서 두 명의 발표자가 “만담”형식으로 재미있게 Code Contract Pex를 함께 사용하는 방법을 소개했습니다.(약간 통통하신 분의 발음이 아주 재미있습니다.) 사실 Code Contracts Pex PDC09에 처음 소개되는 주제가 아닙니다. Pex PDC08에 발표되어 청중의 열혈한 박수를 얻어 낸 바 있으며, Code Contract또한 PDC08에 소개되었으며 Web상에서도 알려진바 있습니다.

 

하지만 이 세션을 볼 당시 전 Code Contract에 대해서는 잘 알지 못했는데 Code Contract Pex보다 더욱 쓸만할 것 같더군요. 어렵지 않게 사용할 수 있으면서도 가벼운 습관을 통해 더 나은 품질의 결과를 얻을 수 있을 거란 생각이 들었습니다. 여러분은 어떤가요? 이 글을 읽으신후 스스로 판단하시기 바랍니다.

 

 

Why the Assertion?

Assertion as Assertion

Assertion, 단언 이라고 표현되는 이 테크닉은 프로그래머가 코드의 특정 지점 내에서 프로그램 논리 흐름상의 반드시 만족해야 하는 ‘가정’을 코드에 넣는 것을 의미합니다. Introduction to Algorithm QuickSort알고리즘에 사용되는 Partition Function을 예로 들어보겠습니다.

 

Partition(A, p, r)

x ß A[r]

i ß p -1

for j ß p to r-1

           do if A[j] <= x

                     then i ß i+1

                                exchange A[i] ßà A[j]

exchange A[i] ßà A[r]

return i+1

 

책에서는 위 알고리즘을 알리는 것으로 끝나는 것이 아니라 다음과 같은 단언이 따라옵니다.

 

For 루프 안에서 다음 3가지 조건이 항상 만족한다.

1.     If p <= k <= i, then A[k] <= x

2.     If i+1 <= k <= j-1, then A[k] > x

3.     If k = r, then A[k] = x

 

3가지 expression이 바로 알고리즘 논리 상의 Assertion입니다. 만약 for 루프 내에서 1,2,3번 중 하나라도 만족하지 않는 것이 있다면 이 알고리즘은 올바르지 않은 것입니다.

다른 예로 최근 포스팅을 들 수 있겠습니다. 해당 포스팅을 보면 알고리즘 나열 도중 -**단언-으로 시작되는 줄이 보입니다. 그들이 제가 생각 했을 때 반드시 참이어야 하는 논리상의 가정입니다.(실제로는 저 단언중 몇가지가 옳지 않아 알고리즘을 수정해야 했습니다.)

프로그래머는 System.Diagnostics Debug 클래스의 Assert( bool condition)메소드를 이용해 Assertion을 코드에 삽입할 수 있습니다. Debug클래스의 Assert는 조건를 만족하지 않으면 메시지와 함께 프로그램을 종료시켜 버립니다. 이런 Assertion의 사용으로 인해 프로그래머는 자신의 알고리즘에 대해 확신을 가질 수 있고, 만약 논리상의 오류가 있을 때 그 원인을 보다 쉽게 추리할 수 있습니다.

 

Assertion as Contract.

Assertion을 프로그래머간의 ‘계약’으로 사용할 수 있습니다. Argument Check가 좋은 예입니다. 관습적으로 Public 메소드의 Argument Check Assertion이 아닌 Exception으로써 명시합니다. 예를 들어 Math 클래스의 Round메소드의 Signiture는 다음과 같습니다.

public static double Round(double value, int digits, MidpointRounding mode);

Visual Studio 상에서 위 메소드의 주석을 펼쳐보면 다음을 발견할 수 있습니다. Digits 메소드가 0보다 작거나 15보다 크면 Exception을 발생시킨다는 것입니다. 즉 이 메소드는 digits argument 0<= digits <= 15라는 전제 내에서 동작하며, 이 메소드를 이용하는 사용자가 이 전제를 지켜주기를 요구하고 있는 것입니다.

//   System.ArgumentOutOfRangeException:

//     digits is less than 0 or greater than 15.

 

이와 같이 프로그래머는 자신의 코드를 최초에 디자인 할 때 반드시 만족해야 할 “최소한의 조건”를 자신 또는 다른 사용자에게 노출 시킬 필요가 있습니다. 이것을 명시하는 것을 “계약”이라 하겠습니다. 이러한 계약의 종류로 크게 다음 3가지를 들 수 있겠습니다.

 

A.    PreCondition

특정 작업이 시작되기 전에 반드시 지켜져야 하는 전제 조건을 의미합니다. 이미 설명한 메소드의 Argument체크가 이에 해당됩니다.

메소드의 시작에 계약 코드를 삽입하며, public 메소드에는 if-then throw exception 코드가 사용되며 private 메소드에는 Assert가 사용됩니다.

 

B.     PostCondition

특정 작업이 끝난 후에 보장되어야 하는 조건을 의미합니다. 예를 들어 Arc Sine 메소드를 디자인 한다고 했을 때 결과 값이 -π/2 ≤θ≤π/2 를 만족하는 Radian값인 θ이라는 것을 보장할 수 있어야 합니다. 메소드의 마지막에 계약 코드를 사용하게 됩니다.

 

C.     Object Invariants

이것은 클래스 내의 모든 특정 작업이 종료된 후에 항상 지켜져야 하는 불변의 조건을 의미합니다. 예를 찾기 힘들어 Reference로 사용한 Programmin with Assertion의 예를 그대로 말씀드리겠습니다. 여러분이 어떤 필요에 있어서 Balanced Binary Tree 를 만들어야 한다고 가정하겠습니다. 이 때 Balanced Binary Tree는 특정 연산이 이루어지기 전이나 후에 “Balanced, Binary”라는 조건을 항상 만족해야 합니다. Tree내의 모든 Node Node자신의 자식의 수가 0보다 같거나 크고, 2보다 같거나 작다는 조건을 항상 만족해야 하며(Binary), 모든 Node Node 자신의 자식들(많아야 2)간의 Depth의 차이가 1보다 같거나 작아야한다는 사실을 만족해야 합니다.(Balanced)

모든 public 코드 뒤에 Object Invariants Assert코드가 존재하는 메소드를 호출하는 것으로 이 작업을 수행할 수 있습니다.

 

 

Break Point!

여러분은 여기까지 읽었을 때 Assertion -- if-then throw 를 제외한 순수 Assertion -- 이 프로그램을 사용하는 사람을 위한 것이 아니라 프로그램을 개발하는 사람들을 위한 것이라고 추측 할 수 있습니다. 그리고 그 추측은 완전히 옳습니다. 또한 이 추측은 또 한가지 결론으로 우리를 이끌어 가는데, 바로 Release시에는 Assert는 존재해야할 이유가 없다는 것입니다. 따라서 보통 아래와 같이 사용합니다.

#if DEBUG

AssertCode..

#end if

하지만 매번 #if DEBUG를 쓴다는 것도 힘든 일이지요. 따라서 우리를 배려한 Microsoft는 Debug.Assert 메소드가 오직 Debug시에만 컴파일되게 했습니다.

 

 

Why the Code Contract?

Code Contract as Assertion

Code Contract는 이름에서 알 수 있듯이 “계약”을 위한 필요와 목적에서 출발했지만 Assertion으로써의 기능도 할 수 있습니다. Contract클래스의 Assert, Assume 메소드가 그것입니다. 이 기능은 기존의 Debug.Assert의 기능과 완전히 동일합니다.

public static void Assert(bool condition);

public static void Assume(bool condition);

이는 물론 DEBUG시에만 컴파일 대상이됩니다. Assert Assume의 차이점은 이 후에 설명하도록 하겠습니다.

 

Code Contract as Contract

Assertion Assertion으로써의 기능만을 수행한다면 아무런 불만이 없습니다. 그러나 Assertion Contract의 기능까지 함께 할 때 몇 가지 불만이 따라오게 됩니다. 대충 생각해 보면 다음과 같습니다.

 

1.     Assertion또는 if-then throw exception를 계약의 목적으로 사용했을 때, 그 계약이 실재로 존재한다는 사실은 Runtime에 그 계약을 어겼을 때에만 확실하게 알 수 있습니다. 이것은 분명히 비극입니다.

2.     PreCondition, PostCondition, Class Invariants 각각의 계약의 특성에 따른 고유의 기능이 필요한데 기존의 Assertion, if-then throw exception은 그러한 요구를 만족시켜줄 수 없습니다.

3.     그놈의 코드 중복 때문입니다.

4.     Interface에 계약을 명시하고 싶습니다.

5.     상위 Type의 계약이 하위 Type에 ‘반드시’ 상속되었으면 좋겠습니다.

6.     컴파일시 바이너리에 포함될지 결정하는 조건을 다양하게 하고 싶습니다.

 

1번의 필요성 때문에 Code Contract 2가지 유용한 기능을 가지고 있습니다. Document Generation Static Verification 기능이 그것입니다. Documentation Generation으로 개발자들은 계약을 보기도 싫은 코드 조각과 런타임시에만 존재하는 Error 메시지가 아닌 분명한 문서로 받아 볼 수 있게 되었습니다.(문서가 더 싫은 가요? ^^) 또한 Static Verification으로 계약을 잘 지켜서 코딩 했는지 빌드 시에 Warning 메시지로 알 수 있습니다.

 

2번의 필요성 때문에 -- 2번의 필요성에 대한 자세한 설명은 다음 포스팅으로 미루겠습니다. -- Code Contract Precondition, PostCondition, Object Invariants에 특화된 별개의 메소드를 고안했습니다. Require, Ensure, Invariant가 그것입니다. 각각의 설명은 다음 포스팅에 자세히 소개하겠습니다.

 

3번은 사실 4번과 5번을 포함합니다. Assertion만으로 Object Invariants를 구현한다고 상상해보시기 바랍니다. 모든 public 메소드의 마지막에 Object Invariants를 확인하기 위한 Assert 코드를 추가해야 할 것입니다. 이러한 중복은 당연히 사라져야 합니다.

 

4번의 필요성은 상당히 중요합니다. Interface는 물론 다형성을 위한 것이지만 계약은 통일되어야만 합니다. 각각의 Interface 구현 클래스가 다른 계약을 가지는 것을 절대 허용하면 안됩니다. 따라서 Interface에 계약을 명시해야 하며, 그 계약은 모든 구현 클래스에 적용되어야만 합니다.

 

5 입니다. virtual 메소드를 가진 Super클래스가 있다고 가정합니다. Virtual 메소드안에 계약코드를 넣었는데 sub클래스에서 이것을 override해 계약 코드를 지우는 것을 허용하면 안됩니다. 때에 따라서 정해진 계약을 ‘강화’시키는 것을 막아야 할 필요성도 있을 수 있습니다.

 

 

Next

Code Contract가 등장하게 된 배경에 대해 간략히 설명했습니다. 여러분이 스스로 생각하고, 상상할 수 있는 권리를 빼앗고 싶지 않기 때문에 Code Contract가 어떻게 이 일을 해냈는지 말하는 것은 다음 포스팅으로 미룹니다.
감사합니다.
 

 

 

References

Code Contracts and Pex : Power Charge Your Assertions and UnitTests

MSDN Magazine : Code Contracts

Code Contract

Code Contract Manual

Programming With Assertions

저작자 표시
신고

Running On Faith - Eric clapton

노래이야기 2009.12.04 23:30 Posted by 아일레프


저작자 표시
신고

Visual Studio Solution File(.sln) Parser

프로그래밍 2009.11.30 23:30 Posted by 아일레프

 

Sln 파일을 Parsing 필요가 생겼습니다. 설마 없을까 싶어 웹을 찾아 보았는데, 딸리는 검색 실력으로 찾은 것은 StackOverflow Visual Studio 2003 Sln Parse Script 정도가 전부였습니다.

 

Visual Studio 2003 Sln Parse Script C#에서 스크립트를 어떻게 이용해야 하는 모르겠고,

Stack Overflow 내용을 사용하고 싶지만 내부적으로 Visual Studio DTE 8.0 인스턴스를 생성해야 한다는 것이 문제여서.. 어쩔 수 없이 무식한 방법(정말 무식하게)으로 직접 만들었습니다.


솔루션 파일의 구조를 알기 위해 참고한 사이트는  Hack the Project and Solution Files 입니다.

 
첨부된 프로젝트는 해당 기능을 하는 Parser입니다.

Solution.Parse(solutionFilePath)로 사용가능합니다. 





저작자 표시
신고

나쓰메 소세키의 '마음'을 읽고

즐거운 책 이야기 2009.11.30 17:51 Posted by 아일레프


마음 - 10점나쓰메 소세키 지음, 오유리 옮김/문예출판사


아는 건 쓸데없이 많아졌는데 느낄수 있는 감동은 점점줄어가고,

 

사회적인 영향력은 어느덧 커지는데, 내가 받을 수 있고, 줄 수 있는 사랑의 크기는 점점 줄어가고 있다.

 

젠장! 너무 쉽게 알아버리는 것이 문제다. 심장을 도려내 피를 쏟아내는 고통없이, 너무 쉽게 얕은 깨달음을 얻어 버리기 때문에,

 

사랑도 선함도 삶의 가치도 여기 저기에 우리가 원하는 정답이 있기에 그것의 소중함을 모른다,

 

 

어렸을  때 보았던 만화영화가 유치해지듯이

 

뜨거운 하나됨의 기적도, 사랑도, 절절했던 이별의 순간도 한숨 크게 쉬고 숫자 하나, , 셋 되뇌이면 잊혀지는 사사로움이 되듯이

 

모든 중요한 가치들이 쉬워져서 그것이 아무것도 아니라 하는 것이 쿨하다고 여겨지는 이 곳에 살고 있다.

 

 

 

 

어영역 2점 더 받기 위해 그 커다란 윤동주의 시의 감동을 통째로 외웠듯이 우리네 삶도 그와 같구나.

 

좀 더 어렵게 공부했어야 했다. 좀 더 어렵게 깨달았어야 했다. 좀 더 어렵게 사랑했어야 했다. 좀 더 어렵게살았어야 했다.

저작자 표시
신고

WPF Dialog 컨트롤들

프로그래밍 2009.11.11 20:00 Posted by 아일레프

 

최근 FolderBrowserDialog 필요한 일이 생겼는데, 아쉽게도 WPF에는 존재하지 않았다. 다행히 검색해보니 ookii.org에서 Ookii.Dialog 이름으로 여러 Dialog들을 공개하고 있었다.

 

 Ookii.Dialogs 사이트를 통해 확인 있다.

저작자 표시
신고
TAG Dialog, WPF

송영길 의원 대정부 질문

분류없음 2009.11.10 21:30 Posted by 아일레프


...

송영길(이하 송) : 그럼 미디어 법은 어떻게 되어야 하나?

정운찬(이하 정) : 네 저는 뭐 헌법 재판소 판결에 따라서 그 이미 개정 방송법이 시행되고 있지 않습니까?
정부로서는 국회에서 제정된 법률을 차질없이 시행되도록 하는 것이 기본 책무라고 생각합니다..

송 : 아니 유효하다고 했지만 사실상 헌법 불합치 결정 아닌가?

정 : ...

송 : 헌법에 위반되고 침해를 했지만 법적 안정성 때문에 일단 무효로 하진 않지만 국회 에서 스스로 이것을 해결 해라 이렇게 결정해준 것 아닌가? 그렇죠?

정 : 네... 그것은 국회의 문제가 아니겠는가?

송 : 네. 그래서 국회에서 이것을 해소해야 할 것 아닙니까?

정 : 그건 총리로서...

송 : 아니 그거 총리로서 판단이 안됩니까? 그렇게 되어 있잖아여 내용이 그렇지 않습니까?

정 : 역시 국회에서…

...중략...

송 :  그러니까 총리께서는  문제가 많지만 유효하기 때문에 집행하는 것이 정부의 임무다 이렇게 말씀하는거죠?

정 : 예 현재로선 그렇습니다…

송 :  그래서 집행하는거죠? 방송법 시행령이 지금 방송위 통과 되서 국무회의 올라오죠 곧?

정 : ...

송 : 네? 그렇습니까?

정 : ... 네..

송 : 통과 시킬겁니까? 국무회의에서?

정 : ...

송 : 집행할겁니까?

정 : ...

송 : 지금 이렇게 심각한 문제가 있는데 국회에서 입법절차에서 심각한 하자를 치유하도록 여야간에 논쟁이 되고 있는 상황에서 이법을 강행처리 해서 유효하다고 했기 때문에 시행하겠다는 겁니까?

정 : 저는 국회에서 제정된 법률은 차질없이 시행하는 것이 기본책무라고 생각을 합니다.

송 : 좋습니다. 그렇다면 세종시법은 왜 시행하지 않습니까?

정 : ...

정:  글쎄 지금 저희가

송 :  국회에서 여야가 합의한 법안 아닙니까?

정 :  ….

송 : 문제가 있습니까? 절차에 하자가 있었나? 

정 : 지금 더 좋은 아이디어가… 있어서 재추진 하는거 아니겠습니까?

송 : 좋은 아이디어가 있어서 세종시법은 법을 시행하지 않고  헌법재판소가 입법 과정에 심각한 하자를 지적했는데 미디어법은 이것을 시행하겠다? 형식상 유효하니까?

... 하략 ... 






저작자 표시
신고

한글 오토마타

프로그래밍 2009.11.04 23:30 Posted by 아일레프

최근 한/영 자동 고침을 지원하는 TextBox를 만들어야 했다. Low level api를 사용하지 않고 단순한 문자열 변환만을 이용해 한/영 고침을 지원하기 위해 어쩔 수 없이 한글 Automata가 필요하게 되었다. 예를 들어, tkfkd 이라고 사용자가 입력했을 때 "사랑"이라고 출력이 나와야 하는데 이는 다음과 같은 동작을 통해 이루어 질 수 있다.

tkfkd -> ㅅㅏㄹㅏㅇ -> 사랑

이 때 ㅅㅏㄹㅏㅇ -> 사랑 으로 변환하기 위해 사용되어야 하는 것이 한글 Automata이다. 웹검색을 통해 알아봤는데 두벌식 한글 입력을 위해서 imhangul에서 사용한 Automata 사이트에 있는 아래 Automata가 가장 괜찮아 보였다.

 

하지만 위 Automata는 키보드의 즉각적인 입력을 바로 한글로 나타내는 것에 목적이 있지만 내가 만들어야 하는 것은 처음과 끝이 정해진 한글 호환 자모로만 이루어진 문자열을 한글로 변경하는 것이기에 위 사이트의 Automata보다 간편해질 수 있는 여지가 있다. 또한 위 Automata는 다음 두가지 측면에서 나와 같은 초보 프로그래머가 구현하기 까다로운 측면이 있었다.

  1. 특정 State는 이전 State의 정보를 필요로 한다.

    위 사이트를 가보면 CxSy이라는 것은 x State까지의 입력을 Commit하고, y State로 이동하는 것을 의미한다고 되어있다. 위 그림에서 5번 State를 보자 5번 state에서 모음입력이 오면 C3S3이므로 3번 State까지의 입력을 Commit하고 3번 State로 이동하게 된다. 이는 9번 State도 마찬가지이다. 자, 어떻게 state가 이전 state의 정보를 가지고 있게 할 것인가? 내 머리로 깔끔한 해결책을 찾기에는 무리였다.

  2. 각 State의 동작을 정하는 분기 조건이 일치하지 않는다.

    위 그림을 보면 특정 State는 분기 조건이 자음입력, 모음 입력 밖에 없는데, 어떤 State는 분기 조건이 v, vc, l, t 4가지 이다. 분기조건이 C, vc, v 3가지인 State도 있다. 이것은 내가 프로그램을 짜기 곤란하게 만들었는데 왜냐면 나는 각 State를 특정 분기가 일어났을 때의 행동을 정의하는 특정 Interface를 구현하게 해서 최종적으로 StatePattern을 사용하고 싶었기 때문이다.

    그래서 새로운 한글 Automata를 구현하기로 결정했다. 그 녀석은 다음과 같다.

    쩝, Automata라기 보다는 State로 표현된 흐름도라고 보는 게 좋을 것 같다. 워낙 허접해서..

    State를 표현하는 원에는 숫자가 있는데 이는 각 State가 관심이 있는 버퍼의 index를 말한다. 그리고 분기조건은 버퍼[관심있는 index]가 자음인지, 모음인지, 글자 end인지 판단하는 것이다.

    또한 Commit, Canbe중C, Canbe자C, Combine등은 함수를 칭한다. 다음과 같은 동작을 한다.

  3. Commit(bu[0~n]) : 지정된 버퍼의 한글 호환 자모를 꺼낸 후 조합해 출력에 더한다. 예를 들어서 Commit(bu0,1)은 버퍼 0번 1번에 있는 한글 호환 자모를 조합해 출력에 더한다는 것이다. Commit(ㅁㅏㅁ)이면 '맘'을 반환한다.
  4. Canbe중C(모음1, 모음2) : 모음 1, 모음 2가 복모음으로 조합될 수 있는 지 검사한다. Canbe중C(ㅗ, ㅏ)이면 true를 반환하게 된다.
  5. Canbe자C(자음1, 자음2) : 자음 1, 자음 2가 복자음으로 조합될 수 있는 지 검사한다. Canbe자C(ㄹ, ㅁ)이면 true를 반환하게 된다.
  6. Combine(문자, 문자) 는 복모음, 복자음으로 조합 가능한 두 한글 호환 자모를 입력 받아 조합한 뒤 반환한다. 예를 들어 Combine(ㄹ, ㅁ)은 ㄻ을 반환한다.

    버퍼가 [ㅅㅏㄹㅏㅇ]이었을 때 동작과정을 보면 다음과 같다.

  7. 0 State (관심 index : 0) - 버퍼[0]이 자음이므로 1자 State로 이동
  8. 1자 State (관심 index : 1) - 버퍼[1]이 모음이므로 2모 State로 이동
  9. 2모 State (관심 index : 2) - 버퍼[2]이 자음이므로 3자 State로 이동
  10. 3자 State (관심 index : 3) - 버퍼[3]이 모음이므로 Commit(bu0,1)를 수행하고 0 State로 이동한다.

    버퍼 - [ㄹㅏㅇ], 출력 - 사

  11. 0 State (관심 index : 0) - 버퍼[0]이 자음이므로 1자 State로 이동
  12. 1자 State (관심 index : 1) - 버퍼[1]이 모음이므로 2모 State로 이동
  13. 2모 State (관심 index : 2) - 버퍼[2]이 자음이므로 3자 State로 이동
  14. 3자 State (관심 index : 3) - 버퍼[3]이 BufferEnd이므로 Commit(bu0,1,2)를 수행하고 0State로 이동한다.

    버퍼 - [], 출력 - 사랑

  15. 0State (관심 index : 0) - Buffer End이므로 Automata를 종료한다.

      

    버퍼가 [ㅁㅏㄹㅁㅇㅡㅁ] 이었을 때의 동작과정은 다음과 같다.

  16. 0 State (관심 index : 0) - 버퍼[0]이 자음이므로 1자 State로 이동
  17. 1자 State (관심 index : 1) - 버퍼[1]이 모음이므로 2모 State로 이동
  18. 2모 State (관심 index : 2) - 버퍼[2]이 자음이므로 3자 State로 이동
  19. 3자 State (관심 index : 3) - 버퍼[3]이 자음이므로 4자 State로 이동
  20. 4자 State (관심 index : 4) - 버퍼[4]이 자음이므로 CanBe자C(bu2,3)인지 검사, CanBe자C(ㄹ,ㅁ)이므로 true, 따라서 버퍼 2,3을 합한다. 이 때 버퍼는 [ㅁㅏㄻㅇㅡㅁ] 가 된다. 그리고 Commit(bu0,1,2)를 수행한 후 State0으로 이동한다.

    버퍼 - [ㅇㅡㅁ] 출력 - 맑

  21. 0 State (관심 index : 0) - 버퍼[0]이 자음이므로 1자 State로 이동
  22. 1자 State (관심 index : 1) - 버퍼[1]이 모음이므로 2모 State로 이동
  23. 2모 State (관심 index : 2) - 버퍼[2]이 자음이므로 3자 State로 이동
  24. 3자 State (관심 index : 3) - 버퍼[3]이 BufferEnd이므로 Commit(bu0,1,2)를 수행하고 0State로 이동한다.

       

    버퍼 - [], 출력 - 맑음

      

    이제는 구현만 남았다. Commit, Canbe중C, Canbe자C, Combine각각의 함수를 만들고 각 State를 다음의 Interface를 구현하게 한다.

    public interface IHangulAutomataState

    {

    HangulAutomataContext HangulContext { get; set; }

    IHangulAutomataState NextState { get; }

    int InteresteBufferIndex { get; }

    void DoStateActionWhenConsonantComes();

    void DoStateActionWhenVowelComes();

    void DoStateActionWhenBufferEndComes();

    }

    public class HangulAutomataContext

    {

    public List<char> Buffer { get; set; }

    public string OutString { get; set; }

    }

    그리고 HangulAutomata는 다음과 같이 구현하면 되겠다.

       

    public class HangulAutomata

    {

    public static string ConvertToCompleteHangul(string sentence)

    {

    HangulAutomataContext context = new HangulAutomataContext { Buffer = sentence.ToCharArray().ToList(), OutString = string.Empty };

    IHangulAutomataState automataState = HangulAutomataFactory.GetAutomataState(0, JamoType.None, context);

    while (true)

    {

    if (automataState.InteresteBufferIndex == context.Buffer.Count)

    {

    automataState.DoStateActionWhenBufferEndComes();

    if (context.Buffer.Count == 0)

    {

    return context.OutString;

    }

    }

    else

    {

    switch (GetJamoType(automataState.HangulContext.Buffer[automataState.InterestedBufferIndex]))

    {

    case JamoType.Consonant:

    automataState.DoStateActionWhenConsonantComes();

    break;

    case JamoType.Vowel:

    automataState.DoStateActionWhenVowelComes();

    break;

    }

    }

    automataState = automataState.NextState;

    }

    }

    }

       

       

신고

코엑스의 도인

끄적끄적 2009.10.31 14:24 Posted by 아일레프
 
어느날 코엑스 길가에 한명의 처녀 도인과 아줌마 도인이 있었더라. 그 중 아줌마 도인이 지나가던 범인에게 부탁하기를
 
“부디 그대의 마음을 넓혀 가난한 자와 헐벗은 자에게 도움을 주고자 하는 일에 작은 정성을 보태 주시오” 라고 하더라.

이 때 믿음이 없는 범인이 그냥 지나치려고 하다가 처녀 도인의 얼굴이 너무 아리따워 걸음을 멈추고 아줌마 도인에게 대답하기를
 
“요즘 시대가 어두워 스스로 깨우쳤다고 하는 어리석은 사람이 많아 내 당신을 믿지 못하겠으니 부디 도인 증명서 하나만 보여주시오” 라고 말하였더라.
 
이에 처녀 도인이 냉큼 자신의 곱디 고운 손으로 지갑에 손을 넣어 도인 증명서를 보여주려 하자 아줌마 도인이 그 손을 막아서며 범인에게 말하길
 
“이 믿음이 없는 자여, 우리가 진정 도인이건 아니건 그대의 작은 정성을 더해 가난한 사람을 구하고 나아가 그대의 하늘에 보물을 더할 수 있거늘, 그대의 믿음이 없어 가난한 자도 돕지 못하고 그대의 하늘에 때묻은 오점만 생기게 되었도다.” 라고 말하며 고개를 돌려 아리따운 처녀 도인과 함께 그 자리를 냉큼 떠나가더라.
 
이에 범인이 잠시 생각하다가 홀로 되뇌이기를
 
“이놈의 이기적인 도인을 보았나, 당신이 도인이 맞다면 도인 증명서하나 보여줌으로써 가난한 이도 도울 수 있고 다른 이가 자신을 통해 하늘에 보물을 쌓을 수 있거늘, 자신의 헛된 오만으로 하늘의 풍요를 줄였도다!”
 
이는 도인이라는 자의 선을 행하는 목적이 오직 자기 자신의 하늘에 보물을 쌓는 것에 있기 때문이라.
오늘날 선을 행하는 대부분의 사람들의 행위가 이와 같으니 어찌 안타까움을 금할 수 있으랴.
 대저 땅에도 구획이 없고 하늘을 나르는 구름에도 자신만의 집이 없거늘, 만물의 영장 인간만이 땅의 소유를 정하더니 이젠 그 소유의 영역을 하늘에까지 넓혀, 모든 아름다움의 가치를 바닥으로 끌어 내리고 있더라.
 
저작자 표시
신고
TAG 도인

최근에 시간은 넘쳐나는데, 만날 사람들은 없고 해서 주구장창 책을 읽어대고 있다. 엄청난 다독가들에 미치지는 못할 양이지만 적어도 1주일에  2권 정도의 책을 읽고 있다. 그러다 보니 왜 난 책을 읽는것일까? 하는 질문을 하고, 스스로 답하게 되었다. 나는 나만의 짜릿함을 위해 책을 읽는다. 아마 이 글을 읽는 당신도 소통에서 출발되는 기막힌 사건들에 대한 경험이 있을 것이다. 그것은 연인들 사이의 육체적 경험이 될 수도 있고 교회 부흥회에서따따따따- 라고 말을 하며 신과 일체감을 느끼는 경험일 수도 있다. --- 아쉽게도 그 모든 것들이 착각일 수도 있지만 ---

책을 읽으면서도 그와 동일한 느낌이 올때가 있다. 시간과 장소를 뛰어넘어 책이란 매개채로 그 이야기의 창조자와 소통하게 되는 놀라운 경험을 하게 될 때가 있는 것이다. 때로는 그가 내 귓가에만 들릴 수 있는 속삭이는 말로 말하기도 하는데 바로 그 때, 그 순간, 나는 짜릿함을 느끼고 하염없이 눈물 흘리게 된다. 나는 바로 그 느낌을 찾기 위해서 책을 읽는다. 운이 좋으면 10권을 읽었을 때 1권을 만나게 된다. 그리고 그 책은 나의 때가 묻은 둘도 없는 나의 친구가 되는 것이다.

 

 

그렇다면 다른 사람들은 왜 책을 읽을까? “그들의 독서엔 뭔가 특별한 것이 있다를 보면 3명의 엄청난 다독가의 얘기가 나온다. 난 이 중에서 정혜윤 PD의 다음 말이 굉장히 인상적이었다.

 

작가의 저서는 자기복제 같은 면이 있다. 작가의 다양한 책을 읽다 보면 작가가 하고 싶은 , 성향, 문체 특징이 있는데 어느 순간 독자인 나와 맞는 순간이 있다. 힘들면서도 재미있는 과정이다. 그리고 아주 재미있는 책을 발견해도 세상에 읽을 책은 너무 많고, 그래서 지금 읽고 있는 책은 다시 읽을 이라고 생각한다. 소설 캐릭터와 현실의 사람들이 다르다고 생각하지 않는다. 그래서 책을 읽을 마치다시 친구처럼 본다. 내가 책을 특별히 면밀하게 기억한다면 아마도 그래서 그런 아닐까.”

 

굉장하다. “다시 못 볼 친구처럼 책을 대한다고 한다. 난 이 문단을 읽고 기존의 책보는 습관을 버리고 정혜윤 PD의 저 말을 머리속에 남기며 책을 보려 노력했다. 정혜윤 PD처럼 기억력이 좋지 않은 탓에 메모장을 하나 들고 사건의 인과관계를 추적해가면서 인물 관계도를 만들고, 시간 순으로 사건을 나열해보기도 한다. 가능한 많은 ‘?’를 남기고, 작가가 내게 말하고자 하는 바를 놓치지 않으려고 뚫어져라 글을 보던 어느 그 순간, 보이지 않는 세계가 열리는 것과 같은 착각을 느낄 정도로 책이 잘 읽혀 지는 경험을 하게 되었다.

 

 

소유냐 존재냐의 서평 토익 990 네이티브를 만들지는 못한다 – 소유냐 존재냐 글을 쓴 이경복씨는 책을 읽을 때 지양해야 하는 태도와 바른 책읽기에 대해 권하고 있다. 이 글은 정말 좋은 글이라서 누구에게나 권하고 싶다.

 

당장 책을 좋아해서 찾아오는 예스24 웹진 칼럼 독자라면 프롬의 이와 같은 통찰은 더욱 의미 있고 중요한 지적이 있겠습니다. 갈수록 독서의 트렌드는 지식에 대한 소유와 과시를 강조하는 분위기입니다. 책들은 갈수록 무언가 외워야 듯한 내용들을 중심으로 나오고, ‘XX해야 YY가지 같은 나열형의 주제 배분이 두드러집니다. 이른바 독서가, 지식인이라고 자처하는 많은 이들은 심지어나는 1년에 권을 읽었다.’라는 수치상의 자랑에 목을 매고, 많은 이들이 전체의 맥락보다는 특정 문구와 경구를 외우고 인용하는 목을 매고 있습니다.

이것도 분명 소유 양식이라는 틀을 벗어나지 못하는 독서일 것입니다. 책이 전하는 메시지는 행간에 있다는 말이 틀린 말이 아니겠지요. 단순히 격언을 외우고, 누가 이런 말을 했다는 사실 자체를 알고 있는 것만으로 독서가 끝난다면 그것은 책이 본질적으로 가지고 있는 기능으로부터 주체를 소외시키는 결과 낳습니다. 프롬이 굳이 소유 양식을 물질적인 것에 한정하지 않은 것도 바로 이러한 우려를 예상했기 때문일 것입니다.

 

이와 같은 메시지는 파트리트 쥐스킨트의 깊이에의 강요에서도 찾을 수 있다. 이 책은 4가지 단편으로 이루어져 있는데 가장 놀랍고 기막힌 이야기는 역시나 마지막에 있는 법. 4. 문학적 건망증은 내가 읽어본 단편 중 단연 최고다. 이 단편에서 화자는 어느날 자신의 책장에서 책 하나를 꺼내 즐겁게 읽는다. 너무 좋은 문장이 나와 밑줄을 치려고 볼펜을 들었는데, 그 문장에 이미 밑줄이 쳐져 있는 것을 발견한다. 그리고 그 글을 계속 읽어 가는데 또 다시 좋은 문장이 있어 볼펜을 든 순간, 또 그 문장에 누군가가 미리 메모를 해 놨다는 사실을 발견하게 된다. 그리고 놀란다. 그 밑줄과 메모는 바로 화자 자신이 이전에 그 책을 읽고 기록한 것이기 때문이다. 순간 화자는 혼란에 빠진다. 열심히 읽은 책이 자신의 기억에서 없다는 것을 알고 비로소나는 왜 책을 읽는가?’라는 질문을 하게 된 것이다. 그리고 마지막 한 문장으로 끝맺음을 내는데 내 기억으로는 그 문장이 그래, 난 내 삶을 변화시켜야 한다였던 것 같다. 이것은 다음 김훈의 메시지에서도 명확하게 드러난다.

 

책 속에 길이 있다고들 그러는데, 내가 보니까 책 속에는 길이 없어요. 길은 세상에 있는 것이지. 그러니까 책을 읽더라도, 책 속에 있다는 그 길을 세상의 길과 연결을 시켜서, 책 속의 길을 세상의 길로 뻗어 나오게끔 하지 않는다면 그 독서는 무의미한 거라고 생각해요.

 

 

오호라, 소유를 넘어서 존재로 향하는 독서가 바로 그것이구나!

 

 

행간의 의미를 무시한채 멋있고 중요한 문장만을 사진찍듯이 머리 속에 외어, 그럴 듯한 상황에 인용하는 것이 아니라, 언젠가 길을 걷다가 자신이 걸어온 발자국을 보았을 때, 그리고 삶 가운데 자신이 낸 목소리를 스스로 듣고 “이것은 그 때 도스토예프스키가 내게 준 생각이었는데..” “이것은 엔도 슈사쿠가 내게 준 선물이었는데라고 묻득 깨닫고 –- 마치 히카루가 자신이 둔 바둑 안에서 사이를 발견했듯이(주1) – 내 마음 깊은 곳에서 그 작가와 연결되어 있는 실을 발견하게 된 후, 내 안에 그가 내게 전해준 생각이 살아 움직이고 있구나 하고 깊이 느끼는 것, 바로 그것에 있구나.

 

 

 

 

 

주1난 이 장면이 고스트 바둑왕에서 가장 감동적인 장면이라 생각한다.

저작자 표시
신고

정말 제 3의 길은 없나?

분류없음 2009.10.07 18:07 Posted by 아일레프

"제 3의 길은 없다"

위는 굉장히 재미있는 글이다. 위의 글은 독일의 우파 기민, 기사당의 승리 원인을 “유럽 중도 우파가 좌파의 많은 아이디어를 채용했다.”라고 규정하는 반면, 좌파의 실패는 그들이 새로운 유권자들의 마음을 사려고 우파 정책을 펼친 것에 원인이 있다고 했다. 결국 유럽의 좌파가 자신의 길이 아닌 제 3의 길로 가려다 완전히 실패했다고 규정한다. 정체성을 상실했다는 말을 덫붙이면서.

여기서 재미있는 것은 우파정당도 역시 좌파 스러운 정책을 펼침으로써 3의 길을 갔는데, 좌파와는 다르게 멋지게 성공했다는 것이다. 이 행보를 우파의 입장보면 좌파가 정체성을 잃어버렸듯이 우파역시 정체성을 잃어 버렸다고 볼 수도 있는 것인데 그들은 자신의 유권자를 잃지 않았다. 이 점은 아이러니컬 하게 들린다. 글쓴이는 이를 두고 우파가 이념과 정책에서 앞서는 좌파를 닮았기에 성공할 수 있었고, 좌파는 이념과 정책에서 뒤지는 우파를 닮으려고 했기에 실패했다고 해석하려 할 수도 있겠지만, 내 생각에는 우파적 정책을 펼쳐 정체성을 잃었다고 생각하는 극 좌론자들의 생각의 유연성 없음에 그 실패의 원인이 있지 않았나 싶다.

세상은 항상 제 3의 길을 원한다. “이 서로의 단점을 버리고 장점을 닮아가 을 이뤄가는 프로세스는 인류가 성장하는 주요 방법이었다. 우리는 늘 제 3의 길로 감으로써 더 배울 수 있고, 더 자랄 수 있다. 난 그것이 바로 성장하는 것이라고 감히 생각한다. 3의 길을 택하는 것은 정체성을 읽는 것이 아니라 더 나은 정체성을 찾는 것이다.


P.S 하지만 왼쪽이냐, 오른쪽이냐를 선택해야 한다면 왼편이 옳은 길이라 믿습니다.

저작자 표시
신고