2015-12-02 3 views
3

Хотите написать простую оболочку для некоторого внешнего модуля perl. Упрощенный пример:Как обмануть проверку прототипа?

use 5.014; 
use warnings; 

#foreign package 
package Some { 
    sub func { 
     my($x,$y) = @_; 
     return $x.$y; 
    } 
}; 

#my own packages 
package My { 
    #use Some(); 
    sub func { Some::func(@_); } 
} 

package main { 
    #use My; 
    say My::func("res","ult"); 
} 

Это хорошо работает и печатает result.

Но теперь я встречаю модуль, который использует прототипы, например. Вышеприведенный пример выглядит как:

package Some { 
    sub func($$) {  # <-- prototype check 
     my($x,$y) = @_; 
     return $x.$y; 
    } 
}; 

При попытке использовать My обертку пакет - он говорит:

Not enough arguments for Some::func at ppp line 16, near "@_)" 

ли возможно «обмануть» на проверку прототипа или я должен написать свою обертку, как это?

sub func { Some::func($_[0],$_[1]); } 

или даже

sub func($$) { Some::func($_[0],$_[1]); } 

ответ

7
&Some::func(@_); # Bypass prototype check. 

Есть и другие варианты.

(\&Some::func)->(@_); # Call via a reference. 
&Some::func;   # Don't create a new @_. 
goto &Some::func;  # Don't create a new @_, and remove current call frame from stack. 

Метод вызова всегда игнорирует прототипы.

+0

Дуп содержит только 'goto & name'. (не считая subref и '*'). Это простой и понятный ответ. – Nemo

+1

«Дубликат» отвечает на ваш вопрос в самом вопросе. Я думаю, что это делает его очень плохим выбором дубликата. Я снова открыл этот вопрос, поскольку этот вопрос намного ясен, чем другой, и более вероятно, что он будет полезен другим. /// 'goto & name' похоже на' & name', но он удаляет фрейм стека из стека. Возможно, вы захотите сделать это с помощью 'croak' (обычно это плохо) или сохранить память, но она немного медленнее. – ikegami

Смежные вопросы