2017-04-17 9 views
3

나는이 함수에 대한 매개 변수가 리터럴 익명의 서브가 아니라 앞에서 정의한 coderefs 인 곳에서 으로 작업하려고 시도하고 있습니다. Router::Resource 나는 코드 중복을 줄이기 위해 이것을하고있다.`&`프로토 타입이있을 때 어떻게 문자 그대로의 서브 쓰레드 대신 coderefs를 사용할 수 있습니까?

다음은 시놉시스의 코드입니다. 이 작동합니다.

# app.psgi 
use 5.024; 
use Router::Resource qw(resource router GET POST); 
my $app = sub { 
    my ($env) = @_; 
    my $router = router { 
     resource '/' => sub { 
      GET { [200, [], ['get /']] }; 
     }; 
     resource '/blog/{year}/{month}' => sub { 
      GET { [200, [], ['get /blog']] }; 
      POST { [200, [], ['post /blog']] }; 
     }; 
    }; 
    $router->dispatch($env); 
} 
__END__ 
$ plackup & 
$ http -b :5000 
127.0.0.1 - - [17/Apr/2017:14:25:28 +0200] "GET/HTTP/1.1" 200 5 "-" "HTTPie/0.9.2" 
get/
$ http -b :5000/blog/2017/4 
127.0.0.1 - - [17/Apr/2017:14:26:15 +0200] "GET /blog/2017/4 HTTP/1.1" 200 9 "-" "HTTPie/0.9.2" 
get /blog 
$ http -b POST :5000/blog/2017/4 
127.0.0.1 - - [17/Apr/2017:14:26:28 +0200] "POST /blog/2017/4 HTTP/1.1" 200 10 "-" "HTTPie/0.9.2" 
post /blog 
$ pkill -f plackup 

따라서, 코드 참조에 문자 익명에서 내부 PSGI 코드를 변경 한 후 :

my $get_root = sub { [200, [], ['get /']] }; 
⋮ 
     resource '/' => sub { 
      GET $get_root; 
     }; 

그런 프로그램이 더 이상 컴파일되지 않습니다 :

$ perl -c app.psgi 
Type of arg 1 to Router::Resource::GET must be block or sub {} (not private variable) at app.psgi line 8, near "$get_root;" 

함수 프로토 타입 GET(&)입니다 .

&이 경우 통과 익명 서브 루틴을 필요 &가 제 1 위치 일 때, 호출자는, perlsub#Prototypes 볼 정렬 sort { … } @listmap { … } 대신 sort sub { … }, @list 등과 같이 축약 구문을 사용할 수있게 첫 번째 인수로 sub 키워드 또는 후속 쉼표가 필요하지 않습니다.

프로토 타입이있을 때 어떻게 문자 기반 서브 시스템 대신 coderefs를 사용할 수 있습니까?

+1

'및 GET ($의 get_root)? –

+0

Сухой27,이 작품, 아래에 적절한 대답을 그래서 내가 당신을 upvote 수 있습니다. – daxim

답변

3

GET \&$get_root 당신이 의견을 참조 것 같은 더 복잡한 표현을위한

, 당신은

GET \&{$get_generic->('get /')} 

\&{...} 작업이 & 프로토 타입으로 사용하기에 적합한 코드 참조에 그 내용을 강제 변환 할 수 있습니다. 마찬가지로 contexts where you want to workaround a \@ or \% prototype@{[...]}%{{...}}을 사용할 수 있습니다.

+0

이것은 작동하지, upvote 있습니다.불행히도, 그것은 나를 위해 적합하지 않습니다. 죄송합니다. 테스트 사례가 너무 단순합니다. 인수를 일반 함수에 넣으면 '... 반드시 블록 또는 하위 {}이어야합니다 (참조 생성자가 아님)'. 코드 :'my $ get_generic = sub {my ($ body) = @_; return sub {[200, [], [$ body]]}; };'.........'GET \ & $ get_generic -> ('get /'); ' – daxim

+0

완벽한! 프로토 타입을 사용하지 않는 것보다이 구문을 선호합니다. – daxim

2

옵션 :

  • 바이 패스 프로토 타입. 에러 메시지의 요청

    &GET($get_root) 
    
  • BLOCK을 제공한다. 에러 메시지의 요청
    GET { $get_root->(@_) } 
    
  • sub { }을 제공한다.

    GET(sub { $get_root->(@_) }) 
    
  • \&으로 시작하는 것을 사용하십시오. 아마`(미등록)

    GET(\&$get_root)