블로그 이미지
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 를 추가해주어 문제를 해결할 수 있었습니다.
  
  사실 위의 문제들은 그리 어려운 문제들은 아닙니다. 코드를 읽으면서 어떻게 돌아가는 지만 살펴보면 금방 알 수 있죠(저같은 경우에는 파일마다 디버그 로그 찍어내면서 파악했습니다 - 필요한 부분만...). 뭐 조금씩 조금씩 알아나가다가 결국에는 제대로 된 거(?) 하나 만들지 않을까요?
신고
TOTAL 483,668 TODAY 7

티스토리 툴바