15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту


ИСПОЛЬЗОВАНИЕ ПАКЕТОВ ДЛЯ ИЗОЛЯЦИИ ПОДПРОГРАММ

Если у вас имеется много подпрограмм, особенно подпрограмм,
которые вы храните в различных файлах, то может возникнуть колли-
зия имен переменных, когда одно и то же имя переменной ис-
пользуется в различных целях. Perl помогает избежать этого с по-
мощью пакетов (packages). Как известно, объявляя локальные пере-
менные для подпрограмм, можно избежать коллизии имен. Однако ес-
ли несколько подпрограмм совместно используют какие-то специфи-
ческие данные, то эти данные могут потребовать глобальной облас-
ти видимости, что как раз и может вести к коллизии имен.
Используя пакеты, можно группировать глобальные данные в частные
пространства имен (name-spaces), вне пределов которых глобальные
переменные не видны, т. е. неизвестны. Рассмотрим приведенный ни-
же простой пример, в котором две подпрограммы (находящиеся в раз-
личных файлах) используют частные, индивидуальные пространства
имен.

# Код в файле one.pl
sub sub_one
{
package demo_one;
$some_data = 10;
}

# * * * * * * * *

# Код в файле two.pl
sub sub_one
{
package demo_two;
$some_data = 20;
}

Как можно видеть, первая подпрограмма использует имя пакета
demo_one, вторая подпрограмма использует имя пакета demo_two. Обе
подпрограммы могут устанавливать и использовать переменную
$some_data без возникновения коллизии имен между одной и другой
глобальными переменными.
Скрипт <знает> имя пакета, в пределах которого находится пе-
ременная, и он организует доступ к ней, использует имя пакета в
качестве префикса к имени переменной. В следующем примере имя па-
кета package_one или package_two добавляется в качестве префикса
к имени переменной some_data:

&sub_one;
&sub_two;

print "Переменная 1 $package_one'some_data\n"
print "Переменная 2 $package_two'some_data\n"

Когда вы используете пакеты языка Perl, можете создать уни-
кальное пространство имен в пределах текущего файла исходных ко-
дов путем помещения инструкции package в начале файла, как пока-
зано ниже:

package some_package_name

$some_data = 1;

sub some_sub
{
return $some_data;
}

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

require 'some_package.pl';
print &some_package_name'some_sub;

ОБРАБОТКА СТРОК
В предыдущих примерах вы научились построению строковых ли-
тералов, используя интерполяцию переменных. Вы также научились
выполнять соединение строковых литералов и строковых переменных.
В этом разделе вы видите, что Perl предоставляет большой набор
функций, с помощью которых скрипты могут манипулировать строками.

ФУНКЦИЯ CHOP
Функция chop удаляет последний символ строки. Она имеет сле-
дующий формат:

$character = chop(Str);

Функция chop возвращает удаленный символ. Скрипты языка Perl
широко используют chop для удаления символа перехода на новую
строку и символа конца строки.

ФУНКЦИЯ INDEX
Функция index осуществляет поиск заданной подстроки в стро-
ке. Она имеет следующий формат:

$location = index(Str, SubStr[, Offset]);

Функция index возвращает индекс первого вхождения подстроки
(SubStr) в строку (Str). Факультативно может быть задан сдвиг от
начала (Offset), после которого начинается поиск. Если подстрока
не найдена, возвращается значение -1. В следующем примере фун-
кция index ищет вхождения подстроки 'па' после третьего символа в
строке 'banana':

print index('banana','na',3); # Выведет 4.
i -
ФУНКЦИЯ RINDEX
Функция rindex ищет последнее, самое правое вхождение под-
строки в строку и возвращает значение позиции первого символа
подстроки. Функция имеет следующий формат:

$location = rindex(Str, SubStr);

Эта функция аналогична функции index, за исключением того,
что она возвращает последнее вхождение, а не первое. Например, в
следующем примере функция rindex используется для определения
последнего вхождения подстроки 'na' в строку 'banana':

print rindex('banana','na'); # Выведет 4

ФУНКЦИЯ LENGTH
Функция length возвращает число символов в строке. Она имеет
следующий формат:

$len = length(Str);

В следующем примере функция length используется для вывода
числа символов в строке:

print length('banana'); # Выведет 6

ФУНКЦИЯ SUBSTR
Функция substr используется для удаления части строки. Она
имеет следующий формат:

$substring = substr(Str, Offset[,Len]);

Функция возвращает подстроку, т. е. часть строки, длина ко-
торой не превышает величины, заданной факультативным параметром
Len. Возвращаемая подстрока строки str начинается с символа в по-
зиции, заданной сдвигом Offset. Если параметр Len опущен, то воз-
вращаемая строка содержит символы до конца строки включительно.
Если параметр Offset отрицательный, то сдвиг вычисляется от кон-
ца строки. Наконец, скрипт может использовать substr как lvalue
для выполнения операции присваивания. Следующий фрагмент кода ил-
люстрирует использование функции substr.

print substr('orange',3); #Выведет 'nge'
print substr('orange',-2); # Выведет 'ge'
print substr('orange',2,2); # Выведет 'an'
$str = 'apple';
substr($str,-3) = 'ricot';
print $str; # Выведет 'apricot'

Примечание: Часто использование операторов языка Perl для регу-
лярных выражений оказывается более эффективным, чем функции
substr. Регулярные выражения обсуждаются ниже в данной главе.

ФУНКЦИЯ JOIN
Функция join соединяет список элементов в строку, разделяя
каждый элемент заданным символом. Она имеет следующий формат:

$new_string = join(Str,List);

Функция join конвертирует каждый элемент списка в строку и
соединяет строки. Следующий фрагмент кода иллюстрирует использо-
вание функции join:

$str = join(',', 0..4,10,20); # Список будет '0,1,2,3,4,10,20'
$strn = join ("\t", $a, $b, $c);# Смешает списки

ФУНКЦИЯ SPLIT
Функция split разделяет содержимое строки на список элемен-
тов. Она имеет следующий формат:

split(Delimeter, Str[,Limit]);

Аргумент Delimeter определяет символ, по которому осущес-
твляется разделение, например, пробел, слово, символ табуляции и
т. д. Факультативный параметр Limit задает максимальное число
элементов, которое может содержать список. Следующий пример ил-
люстрирует использование функции split.

ФУНКЦИИ ДЛЯ ОБРАБОТКИ СПИСКОВ
В рассмотренных ранее в этой главе примерах мы познакоми-
лись с тем, как создать список, сохранить его в качестве значе-
ния переменной, организовать итерации по всем элементам списка и
получить доступ к индивидуальному элементу списка. В этом разде-
ле вы познакомитесь еще с несколькими функциями, которые расши-
ряют набор возможностей для работы со списками.

ФУНКЦИЯ REVERSE
Функция reverse реверсирует элементы списка. Она имеет сле-
дующий формат:

@new_list = reverse(@List);

Функция reverse реверсирует список и возвращает новый ре-
зультирующий список. Следующий пример иллюстрирует использование
функции reverse:

@list = reverse(1..5); # Результат 5,4,3,2,1
@list = reverse(@list); # Результат 1,2,3,4,5

ФУНКЦИЯ SORT
Функция sort сортирует элементы списка. Она имеет следующий
формат:

@new_list = sort(@List);

или

@new_list = sort(Subroutine @List);

или

@new_list = sort(BlockStatement @List);

Функция sort размещает элементы в списке, упорядочивая их в
соответствии с порядковыми номерами символов в таблице ASCII-ко-
дов. Так же как и функция reverse, функция sort возвращает в ка-
честве значения новый список и не воздействует на исходный спи-
сок. Следующий пример иллюстрирует использование функции sort:

@list = sort (1,5,2,3,4); # Результат 1,2,3,4,5
@list = sort(1,2,10); # 1,10,2 сортировка в ASCII

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

@list = sort({$a <=> $b} (2,1,10)); # @list 1,2,10
@list = sort({$b <=> $a}) (2,1,10); # @list 10,2,1

sub mycomp
{
$b <=> $a
}

@list = sort(mycomp (2,1,10)); # @list 10,2,1

ФУНКЦИИ РАБОТЫ С МАССИВАМИ
Как известно, массив представляет собой структуру данных,
содержащую одно или несколько значений величин одного типа, нап-
ример, 100 имен студентов. Perl содержит несколько встроенных
функций, которые помогают работать с элементами массива. В сле-
дующих разделах рассматривается несколько основных функций для
обработки массивов.

ФУНКЦИИ PUSH И POP
Скрипты языка Perl используют фикции push и pop для того,
чтобы добавлять и удалять элементы с конца массива. Иными слова-
ми, функции push и pop позволяют скриптам выполнять операции со
стеком по принципу: последним вошел, первым вышел. Функция push
имеет следующий формат:

push(@ARRAY, LIST);

Следующий фрагмент иллюстрирует использование функции push:

@list = ();
push(@list,10,20); # @list теперь (10,20)
push(@list,1..3); # @list теперь (10,20,1,2,3)

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

$value = pop(@ARRAY);

Следующий фрагмент программы иллюстрирует использование фун-
кции pop:

# Возьмём @list из предыдущего примера

print pop(@list); # Выведет 3
print pop(@list); # Выведет 2

# Теперь @list (10,20)


ФУНКЦИЯ SHIFT
Функция shift удаляет и возвращает элемент из начала масси-
ва. Эта функция аналогична функции pop с тем только отличием, что
работает от начала массива по принципу FIFO (<первым вошел, пер-
вым вышел>). Функция shift имеет следующий формат:

$value = shift(@ARRAY);

Следующий фрагмент программы иллюстрирует использование фун-
кции shift:

# Возьмём @list из предыдущего примера

print shift(@list); # Выведет 10
print shift(@list); # Выведет 20

# Теперь @list ()

ФУНКЦИЯ UNSHIFT
Функция unshift добавляет один или больше элементов к нача-
лу массива. Она имеет следующий код:

unshift(@Array, List);

Следующий фрагмент программы иллюстрирует использование фун-
кции unshift:

# @list = ()
unshift(@list,5,10,20); # @list (5,10,20)
unshift(@list, 1..3); # @list (1,2,3,5,10,20)

ФУНКЦИЯ SPLICE
Скрипты языка Perl используют функцию splice для того, что-
бы извлекать элементы из списка, заменяя их элементами другого
списка. Она имеет следующий формат:

splice(@Array, Offset[, Count[, List]]);

Функция splice извлекает указанное число элементов {Count)
из массива (@Аrraу), начиная с элемента, на который указывает ве-
личина сдвига (Offset), и заменяет элементы элементами другого
списка (List). Если в вызове функции не указан параметр Count,
функция извлекает элементы до самого конца массива. Если в вызо-
ве функции не указан список, элементами которого замещаются ис-
ходные элементы, то функция не добавляет никаких элементов к пер-
воначальному списку. Следующее выражение иллюстрирует использова-
ние функции splice:

@list = 1..10;
splice(@list,1,8,5,6); # @list = (1,5,6,10)

ФУНКЦИЯ SCALAR
Функция scalar определяет число элементов в списке. Она
имеет следующий формат:

Rsult = scalar(List);

Обычно скрипты языка Perl не нуждаются в использовании фун-
кции scalar применительно к массивам, потому что когда скрипт об-
ращается к массиву, записывая его в скалярном контексте, то он
получает в качестве возвращаемой величины число элементов масси-
ва. Тем не менее, скрипты могут использовать функцию scalar в
случаях, когда контекст является неоднозначным или если список не
является массивом. Следующее выражение иллюстрирует использова-
ние функции scalar.

@list = 1..10;
print scalar(@list); # Выведет размер @list

ФУНКЦИЯ GREP
Функция grep фильтрует элементы списка, для которых задан-
ное выражение принимает значение <ложно>. Она имеет следующий
формат:

@list = grep(Expression, List);

Функция grep просматривает элементы списка, подставляя их в
качестве аргумента в заданное выражение. Функция grep присваи-
вает текущее выражение элемента списка переменной $_ и вычисляет
заданное выражение. Если полученное выражение является истинным,
то функция grep добавляет этот элемент к результирующему списку.
Следующий фрагмент программы иллюстрирует использование функции
grep:

@list = grep($_ & 1, 1..10); # @list (1,3,5,7,9)
@list = ('a', '' 'b'); # @list ('a',' ','b')
@list = grep($_ eq '', @list); # @list ('a','b')

Примечание: Если выражение, модифицирует переменную. $_, то ис-
ходный список также будет модифицирован.

ФУНКЦИИ ОБРАБОТКИ АССОЦИАТИВНЫХ МАССИВОВ
Как известно, ассоциативные массивы - это такие массивы, у
которых индексом является не числовая величина, а, например, имя.
В языке Perl имеется несколько встроенных функций, которые упро-
щают обработку скриптами ассоциативных массивов.

ФУНКЦИЯ KEYS
Функция keys возвращает значения ключей, которые отвечают
ассоциативному массиву. Она имеет следующий формат:

@key_list = keys(%Array);

Функция keys возвращает массив ключей в виде регулярного
списка. Следующий фрагмент программы иллюстрирует использование
функции keys:

$ages{'Bob'} = 25;
$ages{'Mary'} = 30;
$ages{'Zack'} = 15;
@list = keys(%ages); # @list будет 'Zack', 'Bob', 'Mary'
@list = sort keys %ages # @ list 'Bob', 'Mary', 'Zack'

for $key (sort keys %ages)
{
print "$key is $ages{$key}\n"
}

ФУНКЦИЯ VALUES
Функция values возвращает обычный массив, состоящий из зна-
чений ассоциативного массива. Она имеет следующий формат:

@value_list = values(%Array)

Функция values возвращает массив значений ассоциативного
массива в виде регулярного списка. Следующий фрагмент программы
иллюстрирует использование функции values:

# Используем значения из предыдущего примера
%ages = ('Bob', 25, 'Mary', 30, 'Zack', 15);

@list = sort values %ages; # @list (15, 25, 30)

@list = %ages; # @list ('Zack', 15, 'Bob', 25, 'Mary', 30)

ФУНКЦИЯ EACH
Функция each осуществляет итерации элементов в ассоциатив-
ном массиве. Она имеет следующий формат:

@key_values = each(%Array);

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

# Используем значения из предыдущего примера
%ages = ('Bob', 25, 'Mary', 30, 'Zack', 15);

while (($name, $age) = each %ages)
{
# Выведем ages
print "$key is $ages{$key}\n";
}


ФУНКЦИЯ DELETE
Функция delete удаляет элементы ассоциативного массива. Она
имеет следующий формат:

Delete $Array{Key}

Следующая инструкция использует функцию delete для того,
чтобы удалить элемент, отвечающий ключу Bob из ассоциативного
массива $Employees:

Delete $Employees{'Bob'}

АРГУМЕНТЫ КОМАНДНОЙ СТРОКИ
Скриптам на языке Perl легко получить доступ к аргументам
командной строки. Всякий раз, когда запускается скрипт, Perl по-
мещает аргументы командной строки скрипта в списочную переменную
@ARGV. Следующий фрагмент программы служит для вывода аргументов
командной строки на дисплей:

while ($arg = shift @ARGV)
{
print "$arg\n";
}

ДОСТУП К ПЕРЕМЕННЫМ ОКРУЖЕНИЯ
Доступ к переменным окружения осуществляется в скриптах на
языке Perl также очень просто. Всякий раз при запуске скрипта
Perl помещает копии переменных окружения в ассоциативный массив с
именем %ENV. В следующей инструкции массив %ENV используется для
вывода текущего каталога:

print "$ENV{PATH}\n"; # Выведет текущий каталог

Кроме получения значений из массива %ENV, скрипты также мо-
гут изменять элементы массива. Такие изменения массива %ENV изме-
нят установку переменных окружения для всякого процесса-потомка,
создаваемого скриптом. Например, следующая инструкция использует
массив %ENV для изменения текущего пути:

$ENV{PATH} = 'c:\\myexec;'.$ENV{PATH};

Примечание: Изменения, которые скрипт делает в массиве %ENV, не
повлияют на исходные переменные окружения. Иными словами, после
окончания работы скрипта переменные окружения системы не изменят-
ся.

Назад | Далее