воскресенье, 21 сентября 2008 г.

Функции. Передача параметров с дополнительными атрибутами

Идея такая: есть некая функция, которой передаются не только параметры, но и атрибуты этих параметров. Что это может быть? Например, команда и нужная строка запроса. Или действие и кличество его повтроений.
   
Можно использовать несколько вариантов. Наиболее простой и понятной пользователю формой, как я думаю, должно быть решение, когда визуально свойство определенного объекта привязывается к этому же объекту. Что-то навроде ООП, только проще, конечно.

Что для этого можно использовать? Анонимные хэши. Объект здесь будет выступать в качестве ключа, а атрибут - значения хэша. Причем, программа даже может ничего и не знать о существовании объектов и их свойств — все это можно и нужно перехватывать динамически.

Начнем с простого - один ключ, один параметр.

Суть: имеется несколько функции внутри другой, внешней. Пользователь вызывает какую-либо функцию из внешней (в нашем случае это simple) и передает ей какой-то параметр.

sub Simple {
 
# Хэш придется сделать глобальным внутри внешней функции, чтобы 
  # внутренние его видели и могли с ним работать

  our %hash = ( @_ );

  # $sub - это ключ хэша. То есть, имя запрошенной функции
  my ( $sub ) = keys( %hash );

  # Испольнить запрошенную функцию
  eval $sub or print @!;

  # Простые внутренние функции, для наглядности
  sub hello {
    my ( $name ) = values( %hash );
    printf
" Hello, %s!", $name;
  }

  sub good_beye {
    my ( $name ) = values( %hash );
    printf " Good Beye, %s!", $name;
  }
}

&Simple( hello => 'Alex' );


Второй случай немного сложнее.
Программа не знает, сколько и какие данные ей были переданы.
Суть: программа может здороваться с человеком несколько раз подряд. Причем, с несколькими людьми, даже я бы сказал, с бесконечным числом совершенно разных людей. Причем здоровается с каждым столько раз, сколько ей указывают. В качестве объектов - имена, в качестве параметров - количество приветствий для каждого имени.

sub Hello {
  # Все, что передали функции хэшем
  my %hash = ( @_ );

  # Теперь ключи хэша в массиве имен
  my @names = keys( %hash );

  # А значения - в массиве количеств повторений
  my @repeat = values( %hash );

  # Дело техники
  for( my $i=0; $i<@names; $i++ ) {  
    $repeat[$i] ||= 1;    
    for
( my $j=0; $j<$repeat[$i]; $j++ ) {      
        printf
" Hello, %s!\n", $names[$i];
    }
  }
}

&Hello( sasha => 3, sveta => 10, Vasya );


Комментариев нет: