[Perl] autovivification

perl에서는 autovivification 이라는 강력하고 어찌보면 생소할 수 있는 기능이 있다.

 

autovivification 이란?

깊은 깊이를 갖는 자료구조에서(deep data structure), 선언과 초기화에 필요한 장황한 코드를 사용하지 않고도 초기화를 진행해 주는 기능이다.

다음 예제를 통해 살펴보자.

use Data::Dumper;

my $fruit_count = {};

print "Before: \n";
print Dumper $fruit_count;

$fruit_count->{apple}++;
$fruit_count->{orange}++;

print "After: \n";
print Dumper $fruit_count;

위 예제의 실행 결과는 다음과 같다.

ahn-soohan@Mac-261:fout/perl_practice $ perl autovivification1.pl 

Before: 
$VAR1 = {};
After: 
$VAR1 = {
          'orange' => 1,
          'apple' => 1
        };

선언하지 않은 orange와apple에 대해서 카운터가 1씩 올라가 있는 것을 볼 수 있다.

이처럼 autovivification 은 잘 활용하면 편한 기능일 수도 있겠지만, 의도치 않은 결과를 나타내면서 악마와 같은 기능을 할 수 있는 양날의 검이다.

다음의 예제를 한 번 살펴보자.

use Data::Dumper;

my $members = {};

print "Before: \n";
print Dumper $members;

print "It exists.\n" if exists $members->{ahn}->{items};

print "After: \n";
print Dumper $members;

결과는 다음과 같다.

ahn-soohan@Mac-261:fout/perl_practice $ perl autovivification.pl

Before: 
$VAR1 = {};
After: 
$VAR1 = {
          'ahn' => {}
        };

위의 소스 코드에서는  ahn이라는 필드를 선언한 적이 없는데도 불구하고, 비교에 쓰였다는 이유만으로 해쉬에 ahn이라는 필드가 생성되어있다. 이 기능의 강력함을 좀 더 잘 살펴보기 위해 더욱 deep한 필드에 대한 실험을 해보면,

use Data::Dumper;

my $members = {};

print "Before: \n";
print Dumper $members;

print "fruit exists.\n" if exists $members->{ahn}->{items}->{fruit};
print "vegetable exists.\n" if exists $members->{ahn}->{items}->{vegetable};

print "apple exists.\n" if exists $members->{ahn}->{items}->{fruit}->{apple};
print "potato exists.\n" if exists $members->{ahn}->{items}->{vegetable}->{potato};

print "after: \n";
print Dumper $members;

print "fruit exists.\n" if exists $members->{ahn}->{items}->{fruit};
print "vegetable exists.\n" if exists $members->{ahn}->{items}->{vegetable};

결과는 다음과 같다.

ahn-soohan@Mac-261:fout/perl_practice $ perl autovivification.pl

Before: 
$VAR1 = {};
after: 
$VAR1 = {
          'ahn' => {
                     'items' => {
                                  'fruit' => {},
                                  'vegetable' => {}
                                }
                   }
        };
apple exists.
potato exists.

없던 ahn뿐만 아니라, 하위 필드인 items와 그 밑에 fruit와vegetable 까지 생성된 것을 볼 수 있다. 게다가, 처음 if문에서는 exists에 걸리지 않았던 조건문이 autovivification후에는 exists에 걸려서 코드의 동작이 달라진 것을 볼 수 있다. 이런 경우는 보통은 개발자가 의도하지 않은 경우가 많으므로, 이런 부분에 대해서 주의를 할 필요가 있다.

autovivification을 사용하지 않도록 하기 위하여

아래 코드 한줄을 추가해주면 autovivification이 일어나지 않도록 할 수 있다.

no autovivification;

위 예제에 이 코드를 추가하여 실행하여 보면 아래와 같은 결과를 얻을 수 있다.

  • 코드:
    use Data::Dumper;
    
    no autovivification; # here!
    
    my $members = {};
    
    print "Before: \n";
    print Dumper $members;
    
    print "apple exists.\n" if exists $members->{ahn}->{items}->{fruit};
    print "potato exists.\n" if exists $members->{ahn}->{items}->{vegetable};
    
    print "apple exists.\n" if exists $members->{ahn}->{items}->{fruit}->{apple};
    print "potato exists.\n" if exists $members->{ahn}->{items}->{vegetable}->{potato};
    
    print "after: \n";
    print Dumper $members;
    
    print "apple exists.\n" if exists $members->{ahn}->{items}->{fruit};
    print "potato exists.\n" if exists $members->{ahn}->{items}->{vegetable};
  • 결과:
    ahn-soohan@Mac-261:fout/perl_practice $ perl autovivification.pl 
    
    Before: 
    $VAR1 = {};
    after: 
    $VAR1 = {};
Advertisements

2016년 그리고 2017년

2016년의 막이 내리고 2017년이 밝았다.
2017년부터는 주1회씩 블로그 포스팅을 하고자 한다. 일일커밋과 비슷한 느낌으로 개발 관련 포스팅을 하고자 한다. 아주 조금이지만 읽어주는 사람이 있고, 설사 읽어주는 이 없더라도 내 개인적인 개발에도 도움이 되리라 믿기 때문에 다른 것보다도 블로그 포스팅을 열심히 해보고자 한다.

2016년 회사일

FreakOut에 입사한지 일년이 조금 더 지났다.

아직도 광고에 관해서 모르는 것이 많고 많이 배워나가는 단계다.

~ 6월: LINE Ad Platform

상반기에는 우리 FreakOut의 자회사 MTBurn에 파견되어 LINE에 광고를 배포하기 위한 플랫폼 개발에 시간을 보냈다. MTBurn에서 개발된 SSP(Supply Side Platform) Hike에 LINE에 필요한 프로토콜을 추가하여 개발하고 이를 위해 Go언어를 배우고 써보는 좋은 기회가 되었다.

애초에 SSP를 개발할때는 OpenRTB에 충실한 프로토콜을 구현하고자 하였으나, LINE에 광고를 내보내게 되면서 변형된 프로토콜을 많이 구현하게 되었다.

FreakOut에서의 업무도 같이 처리하였는데, 우리의 DSP를 Hike와 연결하는 부분을 구현하였다.

~ 10월 Video Ad for LINE

Hike를 통해 LINE Ad Platform과 성공적으로 연결하고, 그 다음 업무는 LINE에 동영상 포멧의 광고를 배포하는 것이었다.

상당히 어려운 부분이 있었는데, 라인의 광고를 사진, 동영상에 상관없이 같은 spot id로 오게 되어 있는데, 사진과 동영상의 광고가격 책정이 다르기 때문에, 내부 경매를 할 시에 참조해야되는 인덱스를 따로 써야되는 문제가 있었다.

이는 인덱스를 두 번 읽어야하기 때문에 시간적으로 퍼포먼스가 상당히 안좋아지는 문제가 생겼다. 이 부분의 해결을 위해서 단순히 연결하는 부분 이외에 우리의 DSP가 갖고 있던 여러가지 문제점들을 최적화하는데 많은 시간을 할애하였다.

다행히 시간을 줄이는데 성공하였고, 완전 만족스럽지는 않지만 실제로 배포를 하기에는 문제가 없는 수준까지는 만들었다. 앞으로 이 부분은 인프라 증설로 해결하지 않을까 생각된다.

~ 12월 Demographic targeting

LINE에 광고를 배포하게 되면서, LINE의 Demographic 정보(연령대, 성별)를 로그에 축적할수 있게 되었다. 이를 LINE면뿐만 아니라 다른 면에도 활용해보기 위한 프로젝트가 다음 업무였다.

우리 회사의 DMP에 audience_id를 기반으로 설정해놓은 segment로 Demographic정보를 추측하는 것이 주요 내용이었다. 단순히 Naive bayes를 사용하여 예측해봤는데 생각보다는 나쁘지 않았다. 예측 결과를 성별과 연령대를 따로 내는 것보다 [성별-연령대]를 묶어서 예측하는 것이 결과가 더 좋았다.

그리 복잡하고 어려운 프로젝트는 아니었지만, 그래도 하둡쪽의 소스코드도 많이 보게 되고, 회사에 들어와서 간단하지만 처음으로 해본 머신러닝 관련 프로젝트여서 상당히 뿌듯하게 한 프로젝트다.

업부면에서 느낀점

손으로 움직이기 전에 설계와 문서 정리부터..

내가 성격이 상당히 급한 편이라 개발자로서는 치명적인 약점인데, 이것을 여실히 느낀 한 해였다. 가장 많이 느꼈던 점은 코드리뷰를 내고 나서 다른 사람들에 비해서 상당히 많은 코멘트들과 리뷰를 받게 되는데, 한두번이 아니었기 때문에 이에 대해 생각을 해봤다.

나의 역량이 모자란 측면도 있었겠지만, 내가 할 수 있는 우선적인 일은 코딩을 시작하기 전에 설계부분에 좀 더 신경을 쓰고 문서 정리를 확실히 해놓는 습관을 들이는 것이다. 문서 정리는 이번 년도에 가장 신경 쓴 부분이고 매니저도 요구한 부분이었고, 매니저의 평가는 괜찮은 편이었다. 하지만 내 스스로 만족스러운 코드를 작성하기 위해서는 더욱 이부분에 충실해야하고, 더 많은 부분 세세한 부분들에 대해서 생각해야겠다고 느꼈다.

그 외 활동

외부 발표

큰 컨퍼런스는 아니고 매월하는 스터디긴하지만 외부에서 해본 첫 발표라 서툴기는 하고 어찌보면 아무것도 아닐수도 있지만 참 뜻깊게 생각한 발표다.

Cousera – Introduction to Natural Language Processing