Search     or:     and:
 LINUX 
 Language 
 Kernel 
 Package 
 Book 
 Test 
 OS 
 Forum 
iakovlev.org

Обьекты и модули

Модуль - это отдельный файл , который может включать один или более namespace. Имя модуля должно совпадать с именем файла. Для получения доступа к модулю используйте префикс use. Для получения доступа к методу модуля используйте MyModule::MyMethod().

Можно также использовать более простой способ доступа к методам из другого модуля - экспорт , при этом синтаксис обращения к такому методу очень прост . Общий механизм экспорта :


 use Exporter;
 use vars qw(@ISA @EXPORT);
 @ISA=qw(Exporter);
 @EXPORT=("function1", "function2", "function3");
 
Exporter - это специальный встроенный модуль. @EXPORT - специальная встроенная переменная.

Рассмотрим пример - модуль Calc :


 # File: Calc.pm
 #
 package Calc;
 
 use strict;
 
 use Exporter;
 
 use vars qw(@ISA @EXPORT);
 
 @ISA=qw(Exporter);
 
 @EXPORT = ("gcd");
 
 # This function calculates the greatest common divisor of two integers 
 sub gcd
 {
     my $a = shift;
     my $b = shift;
 
     if ($b > $a)
     {
         ($a, $b) = ($b , $a);
     }
 
     while ($a % $b > 0)
     {
         ($a, $b) = ($b, $a % $b);
     }
 
     return $b;
 }
 
 1;
 
 
Пример использования функции gcd из этого модуля :


 use strict;
 
 use Calc;
 
 my $a = 200;
 my $b = 15;
 
 print "gcd(\$a,\$b) == " , gcd($a,$b), "\n";
 

Также возможен импорт-экспорт глобальных переменных для нескольких модулей. Такие переменные должны быть обьявлены с префиксом use vars qw($myvar1 @myvar2) Пример использования :


 package MyVar;
 use strict;
 # Declare a namespace-scoped variable named $myvar.
 use vars qw($myvar);
 sub print_myvar
 {
     print $myvar, "\n";
 }
 1;
 
Использование глобальной переменной myvar:

 use strict;
 
 use MyVar;
 
 $MyVar::myvar = "Hello";
 
 MyVar::print_myvar();
 
 $MyVar::myvar = "World";
 
 MyVar::print_myvar();
 
В модулях есть 2 специальных блока - BEGIN и END , которые срабатывают при загрузке и выгрузке модуля :

 package MyLog;
 
 BEGIN
 {
     open MYLOG, ">mylog.txt";
 }
 
 sub log
 {
     my $what = shift;
 
     # Strip the string of newline characters
     $what =~ s/\n//g;
 
     # The MYLOG filehandle is already open by virtue of the BEGIN
     # block.
     print MYLOG $what, "\n";
 }
 
 END
 {
     close(MYLOG);
 }
 
 1;
 
В чем разница между namespace(package) и модулем ? namespace - он же package - это контейнер для пространства имен и методов , например : MyPackage::MySubPack::my_func() , где один модуль ссылается на другой.

Модуль - это отделный файл , который может входить в несколько namespace.

Обьект в перле - это ссылка. Для использования метода обьекта нужно применять префикс $object_ref->method_name(@args).

Обьявим класс Foo :


 #
 # Foo.pm
 #
 package Foo;
 
 sub new
 {
     # Retrieve the package's string.
     # It is not necessarily Foo, because this constructor may be
     # called from a class that inherits Foo.
     my $class = shift;
 
     # $self is the the object. Let's initialize it to an empty hash
     # reference.
     my $self = {};
 
     # Associate $self with the class $class. This is probably the most
     # important step.
     bless $self, $class;
 
     # Now we can retrieve the other arguments passed to the 
     # construtor.
 
     my $name = shift || "Fooish";
     my $number = shift || 5;
 
     # Put these arguments inside class members
     $self->{'name'} = $name;
     $self->{'number'} = $number;
 
     # Return $self so the user can use it.
     return $self;
 }
 
 sub get_name
 {
     # This step is necessary so it will be treated as a method
     my $self = shift;
 
     return $self->{'name'};
 }
 
 sub assign_name
 {
     my $self = shift;
 
     # Notice that we can pass regular arguments from now on.
     my $new_name = shift || "Fooish";
 
     $self->{'name'} = $new_name;
 
     return 0;
 }
 1;
 
Содадим обьект от этого класса :

 use strict;
 
 use Foo;
 
 my $foo = Foo->new("MyFoo", 500);
 
 print $foo->{'name'}, "\n";
 
 print $foo->get_name(), "\n";
 
 $foo->assign_name("Shlomi Fish");
 
 print $foo->get_name(), "\n";
 

В перле возможен явный вызов перегруженной функции базового класса. Для этого нужно применять префикс SUPER. В следующем примере сделан явный вызов assign_name из базового класса , несмотря на то , что он перегружен :


 package Bar2;
 
 use strict;
 
 use vars qw(@ISA);
 
 use Foo;
 
 @ISA=qw(Foo);
 
 sub assign_name
 {
     my $self = shift;
 
     my $name = shift;
 
     # Call the method of the base class
     my $ret = $self->SUPER::assign_name($name);
     if (! $ret)
     {
         $self->{'num_times'}++;
     }
 
     return $ret;
 }
 
 sub get_num_times_assigned
 {
     my $self = shift;
 
     return
         (exists($self->{'num_times'}) ?
             $self->{'num_times'} :
             0
         );
 }
 
 1;
 
Деструкторы в перле реализованы с помощью ключевого слова DESTROY. Он вызывается при выгрузке модуля.

 package Count;
 
 use strict;
 
 use vars qw(@ISA);
 
 use Bar2;
 
 @ISA=qw(Bar2);
 
 sub DESTROY
 {
     my $self = shift;
 
     print "My name was assigned " . $self->get_num_times_assigned() . " times.\n";
 }
 
 1;
 
В перле есть 2 специальных встроенных метода. isa() - если в качестве параметра этой функции задать имя пакета , эта функция определит , является ли текущий обьект потомком от этого пакета. can() - если в качестве аргумента задать имя метода , функция определит , может ли обьект выполнять данный метод.

Оставьте свой комментарий !

Ваше имя:
Комментарий:
Оба поля являются обязательными

 Автор  Комментарий к данной статье