2013/12/03

2013년 Advent calendar들


올해도 어김없이 찾아온 Perl Korea Advent Calendar 2013

http://advent.perl.kr/2013/

전 세계적으로도 다른 Perl관련 Advent Calendar들이 시작되었음

Perl Advent Calendar
http://www.perladvent.org/2013/

Perl6 Advent Calendar
http://perl6advent.wordpress.com/

Catalyst Advent Calendar
http://www.catalystframework.org/calendar/

Dancer Advent Calendar
http://advent.perldancer.org/2013

Future Advent Calendar
http://leonerds-code.blogspot.co.uk/search/label/advent

일본 Perl Advent Calendar
http://qiita.com/advent-calendar/2013/perl

일본 Mojolicious Advent Calendar
http://qiita.com/advent-calendar/2013/mojolicious


그외에도 
Sysadmin Advent Calendar
http://sysadvent.blogspot.kr/

일본에서는 오픈소스 커뮤니티에 Advent Calendar 열풍이 불어서
Dog이나 Cow나 Advent Calendar를 만들고 있음
http://qiita.com/advent-calendar/2013



2013/06/21

PERL_NEW_COPY_ON_WRITE on Windows Perl.

I've found PERL_NEW_COPY_ON_WRITE option at https://metacpan.org/module/DAGOLDEN/perl-5.19.1/pod/perldelta.pod#Performance-Enhancements

This feature was already available in 5.18.0, but wasn't enabled by default.

So I recompiled Perl 5.18.0 with PERL_NEW_COPY_ON_WRITE option on Windows and compared with Non-PERL_NEW_COPY_ON_WRITE Strawberry Perl 5.18.0.

This is the result.


<Test code>

perl -MBenchmark=cmpthese -e "sub A {my ($s) = @_; length($s) } sub B { my ($s) = @_; $s .= 'B'; length($s) } cmpthese(10000, { test1 => sub { my $s = 'A'x1000000; A($s) }, test2 => sub { my $s = 'A'x1000000; B($s) } })"

"sub A" doesn't modify the input string but "sub B" modfies the input string.

* Strawberry Perl 5.18.0

test1  3374/s    --   -2%
test2 3428/s    2%    --

* PERL_NEW_COPY_ON_WRITE version

test1  8905/s  539%    --
test2 1393/s    --  -84%




PERL_NEW_COPY_ON_WRITE option accelerates "sub A" but slows down "sub B".
I'm wondering why "sub B" is much slower in PERL_NEW_COPY_ON_WRITE option.


2013/06/17

Hooking MS windows messages on Wx Perl.

Sometimes you may need to catch a Windows message that is not already handled by wxWidgets, so there is no Wx::Event for it. With a bit of help from the WIN32::API modules it is possible to hook into the WndProc chain for a wxWindow and watch for the message you are interested in.

The magic is in the SetWindowLong function. When used with the GWL_WNDPROC flag it causes a new WndProc to be set for the window, and returns the old one. This lets you write a function in Perl that can get first crack at all the Windows messages being sent to the window, and if you are not interested in them then pass them on to the original wxWidgets WndProc.

#!/usr/bin/env perl
use strict;
use Win32::API;
use Win32::API::Callback;
use Wx;

# Perl port of Python Code: http://wiki.wxpython.org/HookingTheWndProc

{

    package MyFrame;
    use base 'Wx::Frame';

    use constant GWL_WNDPROC => -4;

    # LONG  SetWindowLong(HWND hWnd, int nIndex, LONG dwNewLong);
    Win32::API->Import('user32', 'SetWindowLongW', 'NIK', 'N');
    # LRESULT CallWindowProc(WNDPROC lpPrevWndFunc, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
    Win32::API->Import('user32', 'CallWindowProcW', 'NNIII', 'N');

    sub new {
        my $ref = shift;
        my $self = $ref->SUPER::new( undef,           # parent window
            -1,              # ID -1 means any
            'wxPerl rules',  # title
            [-1, -1],        # default position
            [150, 100],      # size
        );
        # controls should not be placed directly inside
        # a frame, use a Wx::Panel instead
        my $panel = Wx::Panel->new( $self,            # parent window
            -1,               # ID
        );
        # create a button
        my $button = Wx::Button->new( $panel,         # parent window
            -1,             # ID
            'Click me!',    # label
            [30, 20],       # position
            [-1, -1],       # default size
        );
        $self->{newWndProc} = Win32::API::Callback->new(sub { $self->_MyWndProc(@_) }, 'NIII', 'N');
        $self->{oldWndProc} = SetWindowLongW( $self->GetHandle(), GWL_WNDPROC, $self->{newWndProc} );

        return $self;
    }
    
    sub _MyWndProc {
        my ($self, $hWnd, $msg, $wParam, $lParam) = @_;
        # You can process MS Windows messages here.
        print join (',',@_),"\n";
        CallWindowProcW($self->{oldWndProc}, $hWnd, $msg, $wParam, $lParam);
    }

}

{

    package MyApp;
    use base 'Wx::App';

    sub OnInit {
        my $frame = MyFrame->new;
        $frame->Show( 1 );
    }

}

my $app = MyApp->new;
$app->MainLoop;



2013/05/19

Perl 5.18.0 출시

2013년 5월 18일 Perl 5.18.0 버젼이 출시되었다. 5.18은 우리 현대사에서도 의미 있는 날인데 Perl 5.18.0 버젼을 5월 18일에 내놓는 센스를 발휘하다니...

Perl 5.18.0 에서 바뀐 내용들은 https://metacpan.org/module/RJBS/perl-5.18.0/pod/perldelta.pod 에 잘 정리되어 있다.

5.18.0버젼은 5.16.0 버젼이후 1년동안의 개발기간 동안 113명의 개발자에 의해 2100개의 파일, 400000라인의 수정/추가가 이루어 졌다고 한다.

중요한 점만 짚어 보자면..

Unicode 6.2를 지원.

예전에는 암묵적으로 허용되었던 foreach my $item qw/A B C/ { ... } 같은 코드는 ( )를 명시적으로 싸서 foreach my $item (qw/A B C/)  { ... } 처럼 해 주지 않으면 에러가 난다.  

given ~ when 구문과 ~~스마트매치 연산자가 실험적기능(experimental)으로 빠졌다. 그동안 너무 복잡하고 설계에 문제점이 있다고 말이 많았는데 이 기회에 일단 빼놓고 다시 검토할 계획인가 보다. 5.18에서는 해당 문법을 쓰면 경고가 난다.
 참고: https://metacpan.org/module/RJBS/perl-5.18.0/pod/perldelta.pod#The-smartmatch-family-of-features-are-now-experimental

그리고  encoding, Archive::Extract, CPANPLUS 등 코어모듈에서 제외된 모듈들이 제법 있다.
 참고: https://metacpan.org/module/RJBS/perl-5.18.0/pod/perldelta.pod#Module-removals

또 hash의 취약점 공격을 막기 위해 hash에서 값을 뽑아낼때 마다 랜덤하도록 바뀌었다. 이 때문에 테스트에서 에러가 나는 모듈이 종종 있다.  특히 많이 쓰는 JSON::XS모듈도 그 중 하나인데 패치 되기전에 일단 cpan -T JSON::XS 나 cpanm -n JSON::XS 명령으로 테스트과정을 생략하고 설치해서 쓰도록 하면 된다고 한다.(JSON::XS 모듈은 2.34버젼에서 고쳐졌음)
 참고: http://blog.twoshortplanks.com/2013/05/20/5-18-hash-keys/


마지막으로 Perl 5.18.0 버젼은 안타깝게도 우리 곁을 일찍 떠나버린 @am0c 군을 추모하는 글( https://metacpan.org/module/RJBS/perl-5.18.0/pod/perldelta.pod#Obituary ) 이 포함되어 더욱 뜻깊은 버젼이기도 하다.

2013/04/12

How to use ActiveState Perl's unique features in Strawberry Perl

ActiveState Perl supports unique features like PerlScript ActiveX control and new Tcl and  Tkx module.
But they are close-sourced products, So strawberry perl can't provide those features and can't install through CPAN.

I will show you how to steal the features from ActiveState Perl.

1. 
Install Strawberry perl

2.
Get the same version of ActiveState Perl .zip file format from http://downloads.activestate.com/ActivePerl/releases/ and unzip it.

3. PerlScript
Copy ActivePerl-OOOOOO-MSWin32-OOOOO\perl\bin\PerlSE.dll to C:\strawberry\perl\bin
Run cmd.exe as administrator
cd C:\strawberry\perl\bin
Execute "regsvr32 PerlSE.dll" command. (You can uninstall it with "regsvr32 /u PerlSE.dll" command.)

* Open editor and save the following code as "test.wsf" file

<job id="test">
<script language=PerlScript>
    $WScript->Echo("Hello World!");
</script>
</job>

Execute "cscript test.wsf" or double-click "test.wsf" to check to see if PerlScript works or not.

4. Tkx

Copy
ActivePerl-OOOOOO-MSWin32-OOOOO\perl\lib\Tcl.pm
ActivePerl-OOOOOO-MSWin32-OOOOO\perl\lib\Tcl\*

ActivePerl-OOOOOO-MSWin32-OOOOO\perl\lib\Tkx.pm
ActivePerl-OOOOOO-MSWin32-OOOOO\perl\lib\Tkx\*

ActivePerl-OOOOOO-MSWin32-OOOOO\perl\lib\auto\Tcl\*

ActivePerl-OOOOOO-MSWin32-OOOOO\perl\lib\auto\Tkx\*
files and the same folder structure to C:\strawberry\perl\site\lib folder.

ActivePerl-OOOOOO-MSWin32-OOOOO\perl\bin\tkx-ed
ActivePerl-OOOOOO-MSWin32-OOOOO\perl\bin\tkx-ed.bat
ActivePerl-OOOOOO-MSWin32-OOOOO\perl\bin\tkx-prove
ActivePerl-OOOOOO-MSWin32-OOOOO\perl\bin\tkx-prove.bat
files to C:\strawberry\perl\site\bin folder.

Run tkx-ed to check to see if Tkx works or not.



WARNING:
USE AT YOUR OWN RISK. :)

2013/03/13

perlbrew 의 새로운 기능

Perl을 root권한 없이 로컬계정에 설치 및 여러 버젼을 번갈아가면서 쓸 수 있게 해주는 perlbrew 에 upgrade-perl 이라는 새로운 기능이 추가됐다.

perl은 5.16.2 처럼 3단계 버젼번호체계를 가지는데 중간버젼간(예를 들면 5.16.2, 5.16.3)에는 모듈의 바이너리 호환성이 보장되기 때문에 C코드등이 포함되어 네이티브하게 컴파일되는 XS모듈 같은 경우 재설치하지 않아도 그대로 사용 가능 하다. 하지만 맨 마지막 점 아래의 마이너 버젼이 바뀌었을때 perlbrew로 새로 마이너 버젼 업그레이드된 perl을 설치하면 예전 쓰던 모듈을 쓰기 위해서는 이전에 깔았던 모듈목록을 뽑아서 다 다시 설치해주는 번거로움이 있었다.

upgrade-perl을 쓰면 다음과 같이 가능하다.

<perl-5.16.3 버젼을 perl-5.16으로 설치한다. 본인의 경우 verbose -v옵션 스레드사용 -D=usethreads 추가>
$ perlbrew -v install perl-5.16.3 --as perl-5.16 -D=usethreads

(위에서 mod_perl이나 pgsql perl플러그인등 기타 어플리케이션에서 동적Perl라이브러를 연동시키려면 -Duseshrplib 을 추가하고 Dtrace를 사용하려면 -D=usedtrace 추가한다. 그 이외의 옵션은 사용자가 굳이 지정하지 않아도 가장 최적의 옵션을 자동으로 선택하므로 굳이 신경쓸 필요가 없다.)

<버젼을 스위치 한다.>
$ perlbrew switch perl-5.16


<설치된 perl목록보기>
$ perlbrew list
* perl-5.16 (5.16.3)
^-괄호안에 5.16 이름으로 실제 설치된 버젼명이 표시된다.

나중에 5.16.4 버젼이 나왔다고 하면

$ perlbrew upgrade-perl

이라고 하면 위의 경우에는 현재 사용하는 Perl의 바이너리 호환이 되는 버젼(5.16.x)의 최신 버젼이 설치되며 기존에 설치해놓았던 모듈을 그대로 사용가능하다.

더 자세한 내용은 아래링크 참고

https://metacpan.org/module/GUGOD/App-perlbrew-0.59/bin/perlbrew#COMMAND:-UPGRADE-PERL

http://jptrans.naver.net/j2k_frame.php/korean/blog.64p.org/entry/2013/03/13/150202

http://www.modernperlbooks.com/mt/2013/03/upgrade-in-place-with-perlbrew.html