Главная страница


ru.perl

 
 - RU.PERL ----------------------------------------------------------------------
 From : Artem Chuprina                       2:5020/400     24 Mar 2003  16:01:36
 To : Mikhail Polykovsky
 Subject : Re: Re[4]: eval
 -------------------------------------------------------------------------------- 
 
 Здравствуй, Mikhail Polykovsky.
 
 AC>> Здравый подход заключается в том, чтобы поделить две части. А именно:
 AC>> eval "use $module ($sub)";
 AC>> if ($@) { обработка ошибки }
 AC>> ${"${module}::our_var1"} = $var1;
 AC>> ${"${module}::our_var2"} = $var2;
 AC>> $out .= &$sub($var3);
 MP> Спасибо, попробую.
 
 AC>> Возможно, еще придется поиграться с no strict 'refs', если мы под use
 AC>> strict.
 MP> СтоИт. Hе процитирован.
 
 AC>> Hо скорее всего, эта задача свидетельствует об ошибке проектирования этого
 AC>> места.
 MP> С этого места пожалуйста поподробнее, если не трудно...
 
 Характерный способ добыть нужную функцию из нужного модуля (без учета
 обработки ошибок) - 
 
 sub dyn_function {
   my ($module, $sub) = @_;
   eval "require $module";
   return $module->can($sub);
 }
 
 Возвращает указатель на функцию, то есть интерфейс к этому имеет вид
 
 dyn_function($module,$sub)->(@args);
 
 То есть задача изощрений вокруг eval - получить указатель на функцию модуля,
 предварительно при необходимости его загрузив. При этом это будет честная
 reference, а не symbolic.
 
 Hа практике, естественно, поступается несколько хитрее, особенно когда это
 частая операция:
 
 our %DynSeen;
 
 sub dyn_function {
     my ($function_name,$module_name) = @_;
     confess "function is not specified" unless $function_name;
     confess "module name is not specified" unless $module_name;
     confess "module name '$module_name' is insecure" unless $module_name =~ /^([
 a-zA-Z0-9_:]+)$/;
     my $module = $1;
     confess "function name '$function_name' is insecure" unless $function_name =
 ~ /^([a-zA-Z0-9_]+)$/;
     my $function = $1;
     if (!exists $DynSeen{$module}) {
         # try to load module
         eval "require $module";
         if ($@) {
             my $mod_fn = $module.'.pm'; $mod_fn =~ s#::#/#g;
             $mod_fn = quotemeta($mod_fn);
             cluck "$@" if $@ !~ /^Can't locate $mod_fn in \@INC/;
             $DynSeen{$module} = '';
         } else {
             $DynSeen{$module} = {};
         }
     }   
     return undef unless $DynSeen{$module};
     return $module->can($function);
 }
 
 Проверки из работающего кода движка, причем работающего местами под taint
 check. Позволю себе не объяснять детали - если надо, следует таки разобраться
 во всем, что тут лежит в основе. Ключевые слова для perldoc - perltaint и
 UNIVERSAL.
 
 -- 
 Artem Chuprina
 RFC2822: <ran@ran.pp.ru>, FIDO: 2:5020/122.256, ICQ: 13038757
 --- ifmail v.2.15dev5
  * Origin: Leninsky 45 home network (2:5020/400)
 
 

Вернуться к списку тем, сортированных по: возрастание даты  уменьшение даты  тема  автор 

 Тема:    Автор:    Дата:  
 Re[2]: eval   Mikhail Polykovsky   24 Mar 2003 13:37:50 
 Re: Re[2]: eval   Artem Chuprina   24 Mar 2003 13:53:17 
 Re[4]: eval   Mikhail Polykovsky   24 Mar 2003 14:04:32 
 Re: Re[4]: eval   Artem Chuprina   24 Mar 2003 16:01:36 
 Re[6]: eval   Mikhail Polykovsky   24 Mar 2003 16:16:58 
 Re: Re[6]: eval   Artem Chuprina   24 Mar 2003 18:54:41 
 Re[6]: eval   Mikhail Polykovsky   25 Mar 2003 13:31:17 
 Re: eval   Victor Wagner   25 Mar 2003 13:45:05 
 Re[2]: eval   Mikhail Polykovsky   25 Mar 2003 13:54:49 
Архивное /ru.perl/1147791a56465.html, оценка 2 из 5, голосов 10
Яндекс.Метрика
Valid HTML 4.01 Transitional