국가에서 특정 사이트를 직접적으로 차단/통제하는 경우1도 있고 배급 등 라이센스 문제로 국가 제한에 막혀 사용해보지 못하는 미디어 관련 서비스들도 있다. 이런 경우 VPN을 통해 해당 사이트 또는 서비스를 이용할 수 있다. (이러라고 만든 VPN은 아닌 것 같지만;)

물론 유료 VPN을 쓸 수 있지만 자주 사용하는 게 아니라면 비용이 좀 아깝다. 게다가 모든 트래픽이 해당 VPN을 경유하기 때문에 유료든 무료든 보안상 찝찝할 수 밖에 없다. 그래서 저렴하고 안전한 방식은 없을까 고민하다가 AWS의 EC2 Free tier를 활용해 VPN을 구성하는 방법을 찾게 되었다.

AWS에서 EC2 인스턴스 생성하기

AWS의 EC2를 생성 및 사용해본 적이 없다면 다음 글을 참고하자. 내 인스턴스를 생성할 땐 지역은 북미(N. Virginia), 설치 이미지는 ubuntu를 선택했는데 지역은 자신의 용도에 맞게 사용하면 되겠다.

VPN 설치하기

이제 생성한 인스턴스에 VPN을 구성할 차례다. Voodoo Privacy Project에서 제공하는 VPN 설치 쉘스크립트를 사용하면 간편하게 설치할 수 있다.

$ wget https://raw.githubusercontent.com/sarfata/voodooprivacy/master/voodoo-vpn.sh

쉘스크립트를 받은 후 IPSEC_PSK, VPN_USER, VPN_PASSWORD를 안전한 정보로 변경한다.

그다음 관리자 권한으로 설치하면 끝난다.

$ sudo bash voodoo-vpn.sh

맥OS에서 VPN 설정하기

다음은 VPN을 설정할 차례다. 시스템 설정 > 네트워크에서 다음과 같은 절차로 VPN을 생성할 수 있다. 먼저 네트워크 창에서 좌측 하단 + 버튼을 눌러 VPN을 추가한다.

Add new VPN at Network section

서버 주소는 ssh 접속할 때 사용한 주소(ec2-00-00-00-00.compute-1.amazonaws.com 같은 형식), Account Name은 위에서 변경했던 VPN_USER 값이다.

VPN Config

인증 설정 Authentication Settings... 버튼을 누른 후 나머지 설정들은 위에서 작성했던 VPN_PASSWORD, IPSEC_PSK 순으로 입력하면 된다.

VPN Config

그리고 모든 트래픽을 VPN을 통해 받을 수 있도록 고급 Advanced... 버튼을 눌러 Send all traffic over VPN connection을 체크한다. 여기까지 설정한 후 Connect 버튼을 눌러 VPN을 활성화하면 모든 과정이 완료된다.

VPN status in side bar

재빠르게 켜고 끌 수 있도록 사이드바에 등록하는 것도 팁.


EC2 서비스는 사용량에 따라 비용이 청구될 수도 있으므로 조금 주의깊게 보는 것이 좋다. EC2 Free tier 제공 범위를 넘는 트래픽을 만들면 EC2 요금을 내게 되니 유의하자. Free Tier는 월 750시간까지 해당이라 나는 그냥 켜둔 상태로 두고 있고 아직까진 사용량이나 트래픽으로 별다른 요금이 발생하지 않았다.

N 모 유명 스트리밍 서비스의 경우는, 스트리밍이 시작되고 나서 VPN을 꺼도 끊기지 않았다. 사용하지 않을 때는 VPN 접속을 끄면 된다. 물론 VPN 서버를 종료해도 되는데 이런 경우 다시 켰을 때 IP가 변경되어 설정을 변경해야 하는 번거로움이 있어 별로 추천하지는 않는다.

  • 중국의 예를 생각하고 적었지만 적고 나니 한국도 마찬가지. 
  • 얼마 전 처음으로 원격근무를 경험했다. 우리 회사는 상당히 유연한 근무 환경을 제공하고 있어서 꼭 참여해야 하는 미팅이 있는 경우가 아니고서는 원격근무가 가능하다. 지금까지 신청하지 않았던 이유는 근무 환경이 달라지는 것, 내가 집에서 쓸 수 있는 개발 환경이 회사에서보다 제한적이었던 상황이었기 때문에 한번도 이런 형태로 일을 해보지 않았었다. 이번엔 특이하게도 택배를 본인이 수령해야 하는(?) 부득이한 상황이라서 재택근무를 하기로 마음 먹었고 처음으로 집에서 일을 해보게 되었다.

    “집에서 일을 한다”는 생각보다 달랐다

    원격근무는 집에서 일을 하는 것이라고 막연하게 알고 있었지만 내 방 책상에 앉아서 컨퍼런스 콜을 하고 코드를 작성하고 이메일을 작성하고보니 “집에서 일을 한다”라는 문장이 이전과는 조금 다르게 느껴졌다. 그 전까지는 출퇴근을 하면서 조금이나마 전환 시간이 있어서 그랬는지 일과 내 삶이 명확하게 분리되었던 반면에 재택근무는 일상에 업무를 끌어다 놓는 과정으로 느껴졌다.

    업무와 삶이 뒤범벅 되는 일은 재택근무를 하게 될 때 경계해야 하는 부분 중 하나라고는 하지만 가장 이상적으로 일을 할 수 있는 환경을 만드는 일과 같다고 느껴졌다. 일과 일상에서 컨텍스트 스위칭이 빈번하게 일어날 수 있는 환경이라 그 둘이 명확히 분리해야 한다고 생각하는 사람에게는 분명 좋은 환경은 아닐 것이다. 반면 내 일에 더 몰입하고 싶다면 이보다 더 좋을 수가 없다. 아침부터 막히는 출근길, 환승 시간표, 주의력을 분산하게 만드는 수많은 인터렉션들(내 경우엔 SNS)을 마주할 수 밖에 없는데 그 복잡한 과정을 거치지 않고 책상에 앉기만 하면 일을 시작할 수 있어서 좋았다.

    공간 용도 변화

    이제는 당연한 말이지만 인터넷만 연결되어 있으면 어디서든 일을 할 수 있다. 예전에 비해 쉽게 사용할 수 있는 수많은 협업 도구들과 분산 버전관리 도구 덕분에 적은 리소스로도 충분히 업무가 가능해졌다. 우리 회사도 대부분의 코드를 gitlab에서 관리하고 있고 구글앱스와 trello를 활용해 협업하고 있고 컨퍼런스 콜은 skype를 사용하고 있어서 큰 문제 없이 업무를 볼 수 있었다. 이제는 정말 어디서든 인터넷만 가능하면 업무 처리를 할 수 있다. 이런 기술의 발전들이 전통적인 공간 개념을 허물고 있고 원격근무의 문제점도 같이 해결하고 있다.

    멜번은 임대 비용이 비싸서 여러 회사가 큰 오피스를 빌려 같이 공간을 공유해서 쓰는 경우가 꽤 많은 편이다. 우리 회사도 다른 두 회사와 함께 사무실을 공유해서 쓰고 있는데, 하나는 에너지 회사, 다른 하나는 금융 IT 회사다. 전자는 MS의 클라우드 서비스를 기반으로 모든 자료를 공유하고 있어서 잦은 출장에도 업무의 연속성을 유지하고 있고 후자는 VPN을 통해 업무 환경이 구성되어 있어 회사 직원들이 일주일에도 수 차례 시드니와 멜번을 오가며 일을 한다. 시간이 갈수록 더욱 쉽고 저렴하게 구축이 가능해진 업무 환경으로 사무실의 역할이 점점 무형적으로 변하고 있다는 점을 체감한다.

    새롭고 사소한 허들들

    사실 사소한 차이고 아직 경험이 많지 않기 때문에 마주하게 된 일들이지만 출퇴근 할 때 딱히 고민해보지 않았던 새롭고 작은 부분들을 볼 수 있었다.

    살고 있는 곳이 주택가라서 커피를 사 마실 수 있는 곳이 없었다. 처음이라 잔뜩 긴장해서 커피 없이도 하루종일 업무를 할 수 있었지만 반복되다보면 또 커피가 필요한 날이 올 것 같다. 회사 근처에 맛있는 카페에 길들여져 내 커피가 맛없다는 사실을 입이 기억하고 있어서 직접 커피를 내려 마시면 되는 일이지만 그건 또 맛이 없어서(정말 없다) 그렇게 좋은 해결책은 아니다. 겨우 하루 경험이라 은행에 다녀올 일이 없어서 그나마 다행이었지 내 주거래 은행은 커먼웰스인데 집 근처에 커먼웰스도 없다. 회사가 있는 곳들은 항상 집적되어 있기 때문에 식당, 은행 같은 편의 시설도 많이, 가까이 있기 마련이다. 한국처럼 인구밀도가 높아서 어디에서든 상가, 은행을 찾을 수 있는 상황이 아니라면 불편한 경우도 충분히 있음직 하다.

    5시 반에 퇴근을 하고나서 뭘 해야할지 막막했다. 평소에는 교통 상황에 따라 퇴근이 1시간에서 1시간 반 가량 걸리는데 이 시간이 갑자기 생겨나니 어색해서 어쩔 줄 몰라하다가 동네 산책을 하고 왔다. 생각해보면 아침에 일을 시작할 때에도 은근슬쩍 침대에서 뒹굴다가 컴퓨터를 열고 업무를 시작했었다. 아침, 저녁에도 더 효율적으로 시간을 관리한다면 평소에 퇴근하고 저녁 먹고 씻고나면 잘 시간이 되서 아무 것도 할 수 없던 상황보다 훨씬 유익하게 시간을 쓸 수 있으리라 생각된다. 내게도 부양하는 가정이 있다면 아이들과 더 시간을 보내준다거나 할 수 있지 않을까. 일과 일상의 전환에 소비되는 시간을 가용적인 영역 안으로 들어오게 되면 그만큼 쓸 수 있는 시간은 늘어나는데 이번 경험에서처럼 준비되지 않으면 결국엔 출퇴근 하면서 쓰는 그런 시간들처럼 쉽게 지나가버리는데 좀 더 체계적인 계획이 필요한 것 같다.

    그래서 원격근무

    겨우 하루의 경험으로도 이렇게 많은 차이를 느낄 수 있었는데 원격근무를 전사적으로 적용하고 있는 회사들은 어떻게 운영되고 소통하는지 궁금해졌다. 이미 실제로 많은 회사에서 원격으로 일하고 있고 그 과정을 공유하고 있다.

    • 워드프레스 개발사인 오토매틱도 몇 상주 인원 외에는 세계 곳곳에서 퍼져 각각의 공간에서 일을 하고 있다. b2라는 오픈소스 블로그가 더이상 개발되지 않자 이를 대체할 블로그를 오픈소스로 공동작업 한 것이 워드프레스의 시작이다. 모두가 원격으로 업무를 할 수 있는 이유가 아마 이런 배경이 있어서 그런게 아닐까 싶다.

    • Basecamp를 개발한 37Signals1의 원격근무 이야기는 Remote라는 책으로 출판되었다.(최근 위키북스에서 역서를 냈다.) 이 책에서는 원격에서 근무하는 것 자체가 의미를 가지는 것이 아니라 최고의 생산성을 가질 수 있는 장소를 제공하는 것에 의미가 있다고 이야기한다.

    원격근무가 양날의 검이란 것도 맞는 말이지만 인류사에서 따져볼 때 출퇴근하게 된 기간도 얼마 되지 않으니 출퇴근의 장단점을 더 생각해봐야 하지 않을까 싶기도 하다. 그리고 원격근무를 하는가 안하는가의 문제라기보다는 재택근무를 해도 문제가 없는 업무 환경과 여건을 만들 수 있는가가 더 중요한 부분인 것 같다.

    더 읽을 거리

  • 37Signals는 2014년 2월에 사명을 Basecamp로 변경했다. 
  • 최근 회사 프로젝트에서 C# 어플리케이션을 obfuscate 하면서 알게 된 부분들을 정리한 포스트.

    내 (얕은) 지식으로는 컴파일 언어는 “컴파일러를 통해 바이너리로 치환되서 컴파일된 결과물만 가지고 소스를 복구할 수 없다”고 알고 있었는데 현대 언어에서는 그게 그렇게 단순한 부분이 아닌 것 같다. C# 프로그램은 dll이든 exe든 디컴파일러를 통해 내부 구조를 볼 수 있다. 심지어 그런 디컴파일러가 불법적으로 암암리에 유포된다거나 하는 것이 아니라 무료로 공개되어 있기도 하고 다들 많이 사용하는 모양이다. (예를 들면, Jetbrain의 dotpeek.)

    컴파일 언어인데 어떻게 가능하지

    C# 왕초보라 정확한 설명인지는 잘 모르겠지만 이것저것 찾아서 읽어본 글에 따르면,

    • C#은 Common Language Runtime(CLR) 위에서 돌아가는 언어
    • CLR은 MS에서 Common Language Infrastructure(CLI)를 구현한 구현체
    • CLI 규격에 의해 C#도 메타데이터를 포함

    C#의 경우 이 메타데이터가 가지는 장점으로 쉽게 reflection 가능한 구조로 되어 있고 이를 통해 어셈블리의 타입이나 멤버, 메소드, 심지어는 내부 로직까지도 들여다볼 수 있다고 한다.

    좋은 일에 쓴다면 엄청난 효율을 만드는 장점이지만 내부 로직이 공개될 위험이 있다. 그래서 디컴파일을 방지할 수 있는가에 대한 답변을 SO에서 찾아봤는데 대부분 답변이 둘로 수렴했다. 하나는 obfuscate 난독화를 하는 것이고, 다른 하나는 PaaS로 서비스하라는 얘기였다. 현재 프로젝트는 장기적으로 PaaS로 가겠지만 일단은 전자의 방식을 사용하기로 결정했다.

    C# 난독화

    Obfuscation은 코드를 읽기 어렵게 만들어서 내부 로직을 쉽게 들여다볼 수 없게 만드는 과정이다. 메소드, 변수 등을 a, b, c 등으로 수정해서 무슨 로직으로 동작하는지 알아보기 어렵게 만드는 것이다. 목적은 다르지만 결과물로 보면 JavaScript에서 js minify 한 것과 비슷하다.

    Obfuscate하는 도구는 시중에 엄청 많이 나와 있는데 Visual Studio 2012를 설치하면 포함되어 있는 Dotfuscator를 사용했다. Dotfuscator의 사용 방법은 파일 추가 > 결과물 위치 지정 > 실행, 3단계로 아주 단순하다.

    dotfuscator

    다만 Dotfuscator를 하게 되면 모든 클래스, 메소드 등 대부분의 명칭이 a, b, c 와 같이 변하기 때문에 문제가 되는 부분이 있을 수 있다. 가령 JSON을 사용하는 경우라면 Serialize 될 때 해당 멤버변수명을 그대로 사용해야 한다. 그런 경우 다음과 같이 attribute로 예외를 지정해주면 된다.

    class PolicyContainer
    {
        [Obfuscation(Feature = "renaming", Exclude = true)]
        public IList<POLICY> Policys;
    ...
    

    위 attribute와 같이 작성하면 해당 변수는 obfuscate되지 않는다. ObfuscationAttribute Class에서 더 자세한 내용을 확인할 수 있다.

    PHP를 대차게 까는 분들이 가끔 워드프레스 설치하는 환경을 물어보기도 하고 또 환경 설정을 알려주면 설치하면서도 잔소리를 계속 하길래 이런 도구를 소개하는 것도 도움이 될 것 같아 짧게 소개글을 남긴다.

    이제는 일반적인 웹호스팅 비용이나 AWS, Azure와 같은 IaaS의 요금이랑 큰 차이가 없어지고 있는데다 오히려 후자가 저렴한 경우도 많다. 게다가 서버 환경 설정을 마음대로 할 수 없고 해당 호스팅 업체에서 제공하는 서비스가 제한적일 때도 많아서 자연스럽게 가상 서버 환경을 염두하게 된다.

    요즘은 이미 호스팅 환경이 설치되어 있는 서버 이미지를 제공하는 경우도 있고 앱 컨테이너로 쉽게 올릴 수 있는 플랫폼을 제공하는 경우도 많지만 웹호스팅에서 옮겨오려고 고민하는 케이스에는 굉장히 거창하고 막막할 수 밖에 없다. 겨우 필요한건 MySQL, Apache, PHP 환경인데 1) 안전하고 제대로 설치하는게 맞는지, 2) 튜토리얼이 엄청 많은데 어느 글을 따라해야 하는지, 3) 매번 콘솔에서 작업해야 하는지 등 고민이 줄줄이 나온다.

    이 문제를 간단히 해결해줄 호스팅 관리도구 VestaCP가 있다. (No strings attached.)

    명령어 2줄로 LAMP 환경을 모두 설치해주고 함께 설치되는 관리자 화면은 아주 심플한데다 국내 웹호스팅에서 제공하는 기능 정도는 다 제공한다. (SSL 설정, cron 설정 같은 것도.) 추가적인, 세세한 설정이 필요하다면 여전히 콘솔을 통해 작업을 해야 하지만 워드프레스 사이트를 운영한다던지, 간단한 LAMP 환경 개발 같은 경우에는 별도의 수정 없이도 충분히 사용이 가능했다.

    설치는 다음과 같이 가능하다.

    # Download installation script
    curl -O http://vestacp.com/pub/vst-install.sh
    # Run it
    bash vst-install.sh
    

    AWS Free-tier를 사용해도 문제 없이 잘 돌아간다. EC2 Ubuntu 이미지라면 다음과 같이 설치해야 한다.

    # Download installation script
    curl -O http://vestacp.com/pub/vst-install.sh
    # Run it
    sudo bash vst-install.sh --force
    

    회사에서 cPanel (&WHM)과 Plesk를 사용하고 있었다. 이 둘은 엄청나게 세세하고 다양한 기능을 제공하긴 하지만 최근 작업한 magento 기반 프로젝트들은 다른 사이트와 함께 쓰기에는 무거운 감이 있어서 별개의 가상서버를 사용하게 되었고 기존 사용하던 관리도구들이 비용 문제, 고사양이 필요한 문제가 있었다. 그래서 대안을 찾다 VestaCP를 알게 되었고 최근 구축한 사이트는 다 이 관리도구를 이용한 서버에서 운영하고 있다.

    추가적인 설정이 필요한 경우 Vesta 문서를 참고하자.

    한국의 의료보험과 같이 호주에서도 국가에서 제공하는, Medicare라는 의료보험이 있다. 이 비용을 세금을 환급받는 과정에서 공제하는 형태로 납부하게 되는데 호주 영주권자 혹은 시민권자가 아닌 경우에는 해당이 없는 부분이다. 그래서 세금 환급 양식을 작성할 때 Medicare levy exemption 항목을 작성해 납부되지 않도록 해야 한다.

    회계사를 통해서 세금 환급을 하면 이런 부분에 대해 신경 쓸 필요가 없겠지만 내 경우에는 크게 복잡한 부분이 없으니 내 스스로 신청했다. 그러던 중 지난 회계년도에 myTax를 통해서 세금 환급을 신청하는 과정에서 양식을 임시로 저장하려다가 제출해버려서 Medicare levy exemption이 반영되지 않고 환급이 진행되었다.

    세금 환급 중 내용을 잘못 기재해서 수정해야 하거나 추가해야 하는 경우에는 내용 정정 신청 (Amendment request)를 하면 된다. 정정 신청은 요청 양식을 출력해 각 항목을 작성한 후 ATO로 우편으로 발송하거나 팩스로 보내면 된다.

    양식을 작성할 때 다른 부분은 개인 정보 적는 난이라 복잡한 부분이 없고 8번 왜 정정을 요청하는가에 대해서는 구구절절 쓰면 되고 10번 항목 정도가 막막한 부분이다. Qustion number from tax return, Alpha label on tax return 두 항목은 종이 양식에 나온 레이블을 참고해서 작성하면 된다. 내 경우에는 다음과 같이 작성했다.

    Tax Amendment Request

    글씨가… 아하하하하핳

    세금 환급 메뉴얼에는 자국민이 아닌 사람의 Medicare levy exemption에는 추가적인 정보를 요구하지 않는데 나는 혹시나 하는 마음에 내 VEVO Entitlement Check를 출력해 위에서 작성한 양식과 같이 우편으로 보냈다.

    소요되는 시간은 How we process your amendment request 에서 확인할 수 있는데 내가 잘못 작성했음 && 메일 접수에 해당해서 50일이 걸린다고 나왔고 실제로 추가 부분을 환급 받는데 그 정도 시간이 걸린 것 같다.

    위 과정에서 막히는 부분이 있으면 ATO에 전화해서 물어보면 되고 번거로운 분들은 회계사 분들께 연락해서 해결하면 되겠다. 요즘은 개인 세금 환급도 저렴하게 해주는 회계사 분들도 많은데 다음엔 그 분들 통해서 일을 처리해야겠다고 느꼈다.

    ConfigurationManager.appSettingsSerialize해서 다른 곳에 전송하는 것은 어떨까 하는 아이디어를 듣고 코드를 작성해 Json.NET을 사용해서 SerializeObject를 했다. appSettings는 NameValueCollection 클래스인데 Dictionary와 같이 serialize 될 것이라 예상했지만 결과는 키값만 배열로 반환했다.

    var col = new System.Collections.Specialized.NameValueCollection(){
        {"a", "Hello"}, {"a", "World"}
    };
    
    Console.WriteLine(JsonConvert.serializeObject(col));
    // return "[\"a\"]"
    

    NameValueCollection은 하나의 키에 여러개의 값을 가질 수 있는 컬렉션이기 때문에 Dictionary와는 다른 형태로 serialize되도록 NameObjectCollectionBase에서 구현되어 있는 것으로 보인다.

    Console.WriteLine(col["a"]);
    // return Hello,World
    

    동일한 키라도 각각의 값이 독립적으로 보장되야 한다면 조금 복잡해지겠지만 내 경우에는 위와 같이 ,로만 구분 되어도 큰 문제가 없는 상황이라서 Dictionary로 변환한 후에 Serialize하는 방법으로 문제를 해결했다.

    var dict = col.AllKeys.ToDictionary(k => k, v => col[v]);
    
    Console.WriteLine(dict["a"]);
    // return Hello,World
    
    Console.WriteLine(JsonConvert.serializeObject(dict));
    // return "{\"a\":\"Hello,World\"}"
    

    동일한 키에 여러개의 값을 가지는 상황이라면 JSON에선 키 아래 배열로 변환되어야 의미론에 더 맞는 것 같다. 위와 같은 방법 말고도 더 아름답고 쉽고 시멘틱한 방법이 있을 것 같은데…


    GetValues(key)를 이용하면 string[]으로 반환해준다고 한다. how to convert NameValueCollection to JSONstring의 코드를 참고하면 되겠다.

    C#을 쓸 일이 종종 있는데 아직 초보 수준이라서 모르는 문법이 많다. 코드를 읽다가 메서드 선언 앞에 나온 물결 문자를 보게 되었는데 관련된 내용을 찾아봤다. 다음 내용은 함수명 앞에 오는 물결 표시는 무슨 의미인가요?에 나온 답변이다.

    C#에서 메소드 선언 앞에 나오는 ~(물결 문자, 틸드)는 소멸자다.

    • 소멸자는 자동으로 동작하며 명시적으로 실행할 수 없다.
    • 소멸자는 오버로드가 불가능하다. 그러므로 클래스는 최대 하나의 소멸자를 가질 수 있다.
    • 소멸자는 상속되지 않는다. 그러므로 클래스는 하나 이외의 소멸자를 가지지 않게 되고 그 소멸자는 해당 클래스에서 선언이 되어야만 한다.
    • 소멸자는 구조체에서는 사용할 수 없다. 클래스에서만 사용 가능하며 어떤 코드에서도 더 이상 인스턴스를 사용하지 못하게 될 때 소멸될 자격이 주어진다.
    • 인스턴스의 소멸자는 인스턴스가 소멸될 자격만 된다면 언제든 실행이 된다.
    • 인스턴스가 소멸될 때 소멸자는 상속 체인을 따라 자식-부모 순으로 순차적으로 호출된다.

    Finalize

    C#에서 Finalize 메소드는 표준 C++ 소멸자처럼 동작한다. C#에서는 Finalize라고 메소드에 이름 붙이는 것 대신 C++의 소멸자 문법처럼 물결 표시를 메소드명 앞에 붙인다.

    Dispose

    객체를 정리하기 위해 명시적으로 호출이 가능한 메소드 Close() 또는 Dispose()를 제공하는 것이 바람직하다. 소멸자는 GC에 의해 호출되기 때문이다.

    IDisposable 인터페이스는 클래스가 가지고 있는 자원이 정리되어야 한다는 것을 알려주며 실제로 정리될 수 있는 방법을 제공해준다. 만약 소멸자를 직접 구현해야 한다면 그 클래스의 정리(Dispose) 메소드는 GC.SuppressFinalize() 메소드를 꼭 실행해 인스턴스를 강제적으로 제거해야 한다.

    What to use?

    명시적으로 소멸자를 호출하는 것은 허용되지 않는다. 소멸자는 가비지 컬렉터에 의해 호출된다. 만약 file을 다루는 것과 같이 처리 비용이 비싸 관리되지 않는 자원들을 다루게 되면 가능한한 빠르게 닫고 정리하기를 원할 것이다. 이런 경우에는 IDisposable 인터페이스를 구현해야 한다.


    정말 상속되지 않는가

    MSDN의 Destructors (C# Programming Guide)의 예제를 보면 상속은 아니지만 상속 순서에 따른 연쇄 호출(chaining)이 발생한다. 호출의 순서는 가장 하위 클래스의 소멸자부터 상위 클래스로 연쇄적으로 호출한다.

    class First
    {
        ~First()
        {
            System.Diagnostics.Trace.WriteLine("First's destructor is called.");
        }
    }
    
    class Second : First
    {
        ~Second()
        {
            System.Diagnostics.Trace.WriteLine("Second's destructor is called.");
        }
    }
    
    class Third : Second
    {
        ~Third()
        {
            System.Diagnostics.Trace.WriteLine("Third's destructor is called.");
        }
    }
    
    class TestDestructors
    {
        static void Main()
        {
            Third t = new Third();
        }
    
    }
    /* Output (to VS Output Window):
        Third's destructor is called.
        Second's destructor is called.
        First's destructor is called.
    */
    

    요즘은 이와 관련된 웹서비스가 많이 있어서 별도로 프로그램을 설치할 필요 없이 쉽게 이용 가능하다. 다만 업로드할 수 있는 용량에 제한이 있는 경우가 많아서 로컬에서 사용할 수 있는 방법을 찾아봤다.

    PDF 파일의 정보를 확인하거나 추출하기 위해서 pdffonts를 사용할 수 있는데 과거엔 xpdf 라이브러리에 포함되어 있다가 현재에는 poppler 라이브러리를 설치해 사용할 수 있다. 이 라이브러리는 homebrew를 통해 쉽게 설치할 수 있다.

    brew install poppler
    

    폰트 정보를 알아내기 위해서는 다음과 같이 사용할 수 있다.

    pdffonts <파일명>
    

    이미지를 추출할 때는 다음과 같이 쓸 수 있다.

    pdfimages <파일명> <추출 경로>
    

    추출된 이미지가 ppm인 경우는 일반적으로 사용 가능한 포맷인 jpg로 변경해 사용 가능하다. 이 경우엔 imagemagick 라이브러리에 포함되어 있는 convert를 사용할 수 있다.

    해당 라이브러리가 설치되어 있지 않다면 역시 brew를 통해 설치할 수 있다.

    brew install imagemagick
    

    설치가 완료되었으면 다음과 같은 명령어로 일괄 변환할 수 있다.

    convert *.ppm image%d.jpg
    

    여기서 사용된 라이브러리들은 리눅스 패키지 매니저에서도 설치 가능하다.

    WordPress에는 기본적으로 Links라는 포스트 타입이 존재했었는데 WordPress 3.5 에서 제외되었다고 한다. 대부분의 사용자가 거의 이용하지 않는 기능이 되다보니 이런 결정을 내리지 않았나 싶다.

    그 이전 버전 사용자는 업그레이드 하더라도 해당 기능이 계속 유지되지만 신규로 설치한 경우는 다음과 같은 Links 항목을 관리자 화면에서 찾을 수 없다. 이 Links 항목을 보여주는 Link Widget(Blogroll) 또한 존재하지 않는다.

    3.5 이후 버전을 설치한 경우에는 Links가 존재하지 않는다.

    티켓 #21307에서 논의된 결과로 Link Manager 플러그인으로 분리되었고 3.5 이후 버전에서는 해당 플러그인을 설치해 사용할 수 있다.

    Press This는 워드프레스 2.6에서 Press It를 대체하기 위해 나온 기능 중 하나로 워드프레스에 내용을 공유할 수 있도록 돕는 북마클릿 기능이다. 이 북마클릿을 이용하면 어느 웹페이지도 간편하게 스크랩해 자료를 모으거나 해당 컨텐츠를 인용해 포스팅하는데 활용할 수 있다. 그 외에도 언제든 작성할 내용이 생각나거든 북마클릿만 눌러 간편하게 메모할 수 있는 편리한 기능 중 하나다.

    설치하기

    관리자 메뉴 중 Tools > Available Tools에서 Press This 섹션을 찾을 수 있다. 설명대로 Press This 버튼을 bookmark bar에 끌어다 놓으면 설치가 끝난다. (drag and drop)

    (Scrapbook 플러그인을 설치하면 똑같은 페이지에 Scrap This 버튼이 생겨난다. 이 버튼으로 북마클릿을 만들면 Post가 아닌 Scrap으로 수집할 수 있다.)

    press-this

    활용 방법

    저장하려고 하는 페이지에서 북마크바에 끌어다 놓았던 북마클릿을 실행하면 작은 에디터 창이 나타난다. 바로 포스트 하거나 카테고리, 태그 등을 이용해 분류할 수도 있다. 인용하고 싶은 구절이 있다면 해당 영역을 드래그 한 후 북마클릿을 누르면 아래와 같이 간편하게 인용할 수 있다.

    press-this-window

    웹사이트 설정

    웹페이지 색상을 선택하세요

    Darkreader 플러그인으로 선택한 색상이 제대로 표시되지 않을 수 있습니다.