블로그 이미지
JEEN

서울에 사는 꽃청년의 IT찌질모험기

Rss feed Tistory
IT/Perl 2009.01.30 15:53

[ Perl ] 경량프레임워크로 달리는 Perl 웹개발 #2 - MENTA 를 더 만져보기...


  회사업무중에서 MENTA Lib 를 직접 고친 부분와 이유에 대해서 간단하게 읊어보도록 하겠습니다.

   lib/MENTA/Dispatch.pm - Line 16 - 35
  1. -        my $controller = "${cdir}/${path}.pl";
  2. -        my $controller_mt = "${cdir}/${path}.mt";
  3. -        if (-f $controller) {    
  4. -    ~~~ // 중략 //~~~
  5. -            MENTA::finalize($out);
  6. -        } else {
  7. -            die "어쩌구 저쩌구 @{[ MENTA::base_dir() ]} 어쩌구 저쩌구;";
  8. -        }
  대략 컨트롤러와 템플릿 파일이 있었을 경우의 구현 부분을 따로 서브루틴으로 빼내고(run_controller, run_controller_mt) 해당 부분을 지워버렸습니다.
  1. +   my $orig_path = $path;
  2. +
  3. +   while(1) {
  4. +       $path = 'index' unless $path;
  5. +       my $controller = "${cdir}/${path}.pl";
  6. +       my $controller_mt = "${cdir}/${path}.mt";
  7. +       if (-f $controller) {
  8. +              MENTA->context->prepare_path($path, $orig_path);
  9. +       return run_controller($controller, $path, $orig_path);
  10. +       } elsif (-f $controller_mt) {
  11. +       return run_controller_mt($controller_mt, $path, $orig_path);
  12. +       } else {
  13. +       my @tmp_ = split "/", $path;
  14. +       pop @tmp_;
  15. +       $path = join "/", @tmp_;
  16. +       }
  17. +   }

  대충 이와 같습니다. 저렴하게 적어놔서 별거 없습니다만...
  MENTA 의 경우는 /blah/blah/blah 로 접속했을 때.. /app/controller/blah/blah/blah.pl 이나 .mt 파일이 항상 존재해야합니다. 그렇지 않으면 에러페이지가 나오죠. 위의 부가된 처리는 /blah/blah/blah에서 파일이 없다면 /blah/blah 의 파일을 읽어오게 하고... 그게 아니면 계속 상위 페이지의 파일유무를 체크하고 그 파일이 있다면 그것을 읽어오게 합니다.
  그리고 컨트롤러가 존재한다면 prepare_path로 그 경로 정보를 설정하게 합니다. /blah.pl 이 있고, /blah/blah/blah 로 접속했을 때, blah/blah 는 HTTP 쿼리 파라메터가 아닌 별도의 파라메터로 읽어들여집니다. 그 내용은 아래와 같습니다.

  1. diff --git a/lib/MENTA/Context.pm b/lib/MENTA/Context.pm
  2. index e70e729..1122a8a 100644
  3. --- a/lib/MENTA/Context.pm
  4. +++ b/lib/MENTA/Context.pm
  5. @@ -1,7 +1,7 @@
  6.  package MENTA::Context;
  7.  use strict;
  8.  use warnings;
  9. Class::Accessor::Lite->mk_accessors(qw/config plugin_stash request/);
  10. Class::Accessor::Lite->mk_accessors(qw/config plugin_stash request path_args/);
  11.  
  12.  sub new {
  13.      my ($pkg, %args) = @_;
  14. @@ -19,4 +19,13 @@ sub mobile_agent {
  15.      };
  16.  }
  17.  
  18. +sub prepare_path {
  19. +    my ($self, $controller, $path) = @_;
  20. +    
  21. +    return $self->path_args([]) unless $path;
  22. +
  23. +    $path =~ s/^$controller\///g;
  24. +    my @args = split /\//, $path;
  25. +    $self->path_args([ @args ]);
  26. +}
  27.  1;

 뭐없죠? 그리고는 blah.pl에서는 
  1. use MENTA::Controller;
  2.  
  3. sub run {
  4.   my $c = MENTA->context;
  5.  
  6.   warn $c->path_args->[0]; # blah
  7.   warn $c->path_args->[1]; # blah
  8.  
  9.   # blahblah code
  10. }
  이런식으로 그 경로 인수들을 뽑아냅니다.  
  그리고 다른 수정개소는 아래와 같습니다.
  1. diff --git a/lib/MENTA/Controller.pm b/lib/MENTA/Controller.pm
  2. index 6aee162..d9e1166 100644
  3. --- a/lib/MENTA/Controller.pm
  4. +++ b/lib/MENTA/Controller.pm
  5. @@ -21,7 +21,7 @@ sub import {
  6.          my $pkg = do {
  7.              local $_ = (caller(0))[1];
  8.              s{^$controller_dir/*|\.pl$}{}g;
  9. -            s{/}{::};
  10. +            s{/}{::}g;
  11.              "MENTA::Controller::$_";
  12.          };
  13.  
  14.  

  사실 이것을 수정하지 않으면 /blah/blah/blah 의 접속시 /app/controller/blah/blah/blah.pl 이 있는 경우에는  항상 아래와 같은 에러로 끝나게 됩니다.
syntax error at /home/blah/blah/app/controller/blah/blah/blah.pl line x, near ";"MENTA::Controller::blah::blah/blah" 
(Might be a runaway multi-line // string starting on line 3
  힌트는 항상 에러메시지에 담겨 있습니다. 
  일반적으로 /blah 로 접속했을 시의 해당 컨트롤러는 MENTA::Controller::blah 라는 namespace 를 가지게 됩니다. 그런데  /blah/blah/blah 로 접속했을 경우의 에러메시지는 마지막의 namespace 구분자가 / 로 되어 있는 것을 볼 수 있습니다. 원인은 이것이었습니다. 그러므로 위의 코드의 10번째 줄과 같이 g modifier 를 추가해주어 문제를 해결할 수 있었습니다.
  
  사실 위의 문제들은 그리 어려운 문제들은 아닙니다. 코드를 읽으면서 어떻게 돌아가는 지만 살펴보면 금방 알 수 있죠(저같은 경우에는 파일마다 디버그 로그 찍어내면서 파악했습니다 - 필요한 부분만...). 뭐 조금씩 조금씩 알아나가다가 결국에는 제대로 된 거(?) 하나 만들지 않을까요?
신고
IT/Perl 2009.01.27 17:38

[ Perl ] 경량프레임워크로 시작하는 웹개발


  일본의 유명 Perl 해커 tokuhirom 씨에 의해 만들어진 MENTA 는 한때 Mojo 가 불러일으킨 경량프레임워크 붐을 타고 만들어진 프레임워크입니다. 지금 소개하는 것도 상당히 늦은 감이 없지 않아 있지만... (사실은 실제로 써볼 엄두가 안나봐서 안쓰고 있다가, 업무상으로 쓰게 될 일이 생겨서 이렇게 건드리게 되었습니다.)

 일단은 가볍게 설치부터...

svn export http://svn.coderepos.org/share/lang/perl/MENTA/trunk ~/menta

 로 export 하면 대략 다음과 같은 디렉토리 구성이 나옵니다.
app 
 - app/controller : 어플리케이션을 정의
 - app/data  : 어플리케이션에서 사용할 데이터 (SQLite DB file 따위)
 - app/static : 그림파일, CSS, Java Script
extlib - 저자에게 엄선된 CPAN 모듈
lib - MENTA 가 정의된 라이브러리 디렉토리
plugins - MENTA 에서 사용할 플러그인
t - MENTA 자체의 테스트코드

 튜토리얼등은 MENTA 의 STANDALONE 서버를 돌리면 자세하게 소개되어 있고(app/controller/*), 아래의 MENTA 홈페이지에서도 소개되어 있습니다.
 PHP 스러운 템플릿 파일(.mt)을 준비해서 HTML과 Perl 코드를 혼용해서 쓸 수 있죠. 
 CGI 서버 뿐 아니라, Mod_Perl 로도 돌릴 수 있기 때문에 어느 정도 규모에서도 써볼만 하지 않을까 싶습니다.

  * STANDALONE 서버 가동 (기본 포트는 5555)
./bin/cgi-server 

  * Mod_Perl 사용예제는 매뉴얼 페이지를 참고하세요. (http://gp.ath.cx/menta//manual/mod_perl)

 컨트롤러는 .pl 파일이나 .mt 파일로 지정합니다. 그리고 .pl 은 반드시 최소한 아래와 같은 구조로 되어 있어야 합니다.
use MENTA::Controller;

sub run {
  # blahblah...
}

 MENTA::Controller 를 use 했을 때, 기본적으로...
use strict;
use warnings;
use utf8;
 을 깔고 들어가기 때문에 추가로 지정해줄 필요는 없습니다.
 그리고 .mt 의 경우는 자동으로 렌더링되지만, .pl 의 경우는 템플릿을 지정해서 렌더링해주거나, 다른 HTTP Response 를 지정해줘야 합니다.
  OOP 에 목메지 않고도 간단하게 쓸 수 있는 여러 튜토리얼들이 준비되어 있기 때문에 별다른 설명은 필요 없을 것 같네요.
  개인적으로 필요한 기능이 있다면 MENTA lib 를 직접 건드리는 것도 좋겠지만, 대개의 간단한 공용기능을 정의하려면 plugins/* 에서 정의할 수 있습니다. 저같은 경우에는 MENTA 코어를 건드리지 않으면 좀 번거로워지기때문에 MENTA, MENTA::Dispatch, MENTA::Context 를 만지기도 했습니다.
  Perl 에 대해서 별로 모르거나, 혹은 Perl 로 하는 웹개발에 관심이 있으시다면 Catalyst 처럼 학습비용이 큰 것이 아닌 이런 경량 프레임웍부터 시작하는 것도 괜찮지 않을까 생각됩니다.

신고
TOTAL 462,386 TODAY 13

티스토리 툴바