ИСПОЛЬЗОВАНИЕ ПАКЕТОВ ДЛЯ ИЗОЛЯЦИИ ПОДПРОГРАММЕсли у вас имеется много подпрограмм, особенно подпрограмм,которые вы храните в различных файлах, то может возникнуть колли- зия имен переменных, когда одно и то же имя переменной ис- пользуется в различных целях. 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, не повлияют на исходные переменные окружения. Иными словами, после окончания работы скрипта переменные окружения системы не изменят- ся. |