На самом деле Perl является достаточно мощным языком, и поддерживает различные типы и операции над ними, но для новичков некоторые операции являются непривычними, и могут не согласовываться со знаниями полученными из других языков
Дальнеший материал изложен на основе моего диалога с одним новичком в Perlе
1) Итак общеизвестно, что в Perl имеются 4 основных типа данных - скаляр $ (Число, строка или ссылка), массив @ (Одномерный массив скалярных элементов), хеш % (Ассоциативный массив) и процедура & (Исполняемый кусок кода, в Perl исполняемый код почти наравне с данными)
Мы можем с легкостью создавать ссылку на любой из данных элементов, с помощью оператора \, это будет так называемая жесткая ссылка
$sv_vr="ABC";# Создали скалярную переменную типа строка, напомню что двойные кавычки отличатся от одиночных наличием интерполяции (Подстановки переменных в них)
$sv_ref=\$sv_var;# Создали ссылку на это скалярную переменную
@ar_vr=(1,2,3);# Создали массив из численных элементов
$ar_ref=\@ar_vr;# Создали ссылку на этот массив
Для получения доступа к объекту обратно по ссылке, применяется символика данного типа
$n_sv_vr=$$sv_ref;# В переменной $n_sv_vr получим копию, сделанную с переменной $sv_vr
@n_ar_vr=@$ar_ref;# В переменной @n_ar_vr получим копию, сделанную с переменной @ar_vr
Заметим, что если копировать только ссылка на объекты, но сами объекты разумеется копироваться не будут, чего и следовало ожидать
Таких уровней вложенности может быть сколь угодно много, кстати именно таким же образом можно создавать многомерные массивы, то есть в многомерном массиве на самом деле будут храниться не другие массивы, а просто ссылки на них, что весьма логично
@a1=(1,2,3);@a2=("a","b","c");# Создали два массива
@am=(\@a1,\@a2);# Создали массив ссылок на массивы
print${$am[0]}[1];# Выведет 2, так как $am[0] это фактически ссылка на массив @a1, @{$am[0]} это фактически ключ доступа к массиву @a1, тогда ${$am[0]}[1] это второй элемент массива @a1 (Нумерация разумеется, с нуля) Кстати необходимо помнить, что в пути доступа к некоторому конечному элементу многомерного массива (То есть не к подмассиву, а именно к конечному элементу) могут встречаться только знаки [b]$[/b] (И некоторые другие), но знаков [b]@[/b] быть не может в принципе, если они у вас вдруг встретились, то это логическая ошибка
Способ указанный выше, работает хорошо, однако на практике создание многомерных массивов таким образом, а также доступ к их элементам может быть затруднителен, поэтому используется альтернативная схема доступа
$am=[[1,2,3],["a","b","c"]];# Фактически то же самое, что и выше
print$am->[0]->[1];# Выведет 2 как и выше, только теперь не нужно шаманство с фигурными скобками и знаками [b]$[/b]
print$am->[0][1];# То же самое, так как оператор [b]->[/b] немного изменяет функцию квадратных скобок, и как бы подставляет [b]->[/b] между скобками автоматически Если вам не нужно такое поведение, то придется использовать способ, указанный выше (С фигурными скобками и знаками [b]$[/b])
Все это также отлично работает и с хешами, только все квадратные скобки меняются на фигурные, и заместо индексов массива появлятся ключи хеша Разумеется, с помощью первого способа также можно работать с хешами, но мы рассмотрим более простой, второй способ
$hc={x=>{a=>1,b=>2,c=>3},y=>{m=>4,n=>5}};# Создаем многомерный хеш (Обратите внимание на отсутствие кавычек у ключей хеша, это можно делать для анлгийский слов без пробема, иначе кавычки обязательно нужны)
print$hc->{y}{m};# Выведет 4, все по полной аналогии с массивами, как и обещалось ранее
Что касается процедур, то с ними тоже можно делать много интересного, но это будет рассмотрено отдельно
Итак, на этом можно закончить краткий экскурс, к типам данных и ссылкам? Нет нельзя, потому что обычно из ассмотрения выбывают еще два важных типа, которые важные сколько применением, сколько некоторыми важными сведениями об общих сведениях о ссылках
Эти типы данных - FILEHANDLER и FORMAT, и предназначены они соответственно для работы с файловыми дескрипторами и щаблонами форматов Чем же они так особенны? А тем что весь предыдущий механизм использования ссылок для них не будет работать
fopen(FH,"file.txt")# Именно таким образом создается файловый дескриптов FH
format FM ...# На самом деле форматы используются редко, а в web-программировании вообще не нужны, но тут дело принципа
И что же мы видим, получаем что переменная одного из этих типов в Perl, не имеет никакого значка - идентификатора типа, и собственно разыменовать ее никак нельзя, равно как нельзя поставить знак получения ссылки \ перед ней Как же быть? На самом деле можно воспользоваться другим подходом, к Perl-переменной можно обращаться другим методом
*vr_name;# Означем все переменные с именем vr_name - это может быть и скаляр, и массив, и тот же FILEHANDLER Такое имя переменной со [b]*[/b] называется TYPEGLOB
*FH{FILEHANDLE};# То же самое, что и FH при подстановке в дескриптор, но такая переменная уже является настоящий
$fh_rf=\*FH{FILEHANDLE};# А вот таким образом, мы получили заветную ссылку на дескриптор FH
Хотя это и будет работать, на практике такой подход применяется редко, дело в том что Perl в некоторых случаях может по общему TYPEGLOB сам выбирать нужный подтип (Это в первую очередь касается FILEHANDLER), и поэтому допустима такая запись
fopen(*FH,"file.txt");# Perl сам подставил заместо *FH выражение *FH{FILEHANDLER}, учтите что в Perl переменные создаются на ходу
Таким образом мы в общих чертах разобрались с типами данных и ссылками, что поможет разобраться в коде многих Perl-программ Пока что за рамками рассмотрения оказались контексты выполнения, ссылки на процедуры, символические ссылки и еще несколько важных вещей, но мы обязательно вернемся к их рассмотрению в других статьях
2) Основными и используемыми по умолчанию в Perlе являются глобальные динамические переменные, которые как бы никогда не создаются и не удаляются, с ними можно работать по первому обращению, а чтобы очистить содержимое переменной можно присвоить ей значение undef
Однако в Perl также можно создавать локальные и лексические переменные, что тоже связано с определенными особенностями, которые как раз стоит рассмотреть
our$sv;# То же самое что и просто $sv, от такого объявления ничего по сути не меняется, если выключена use strict
Предже чем рассмотреть локальные и лексические переменные, надо определиться с понятием области видимости Если использовать только глобальные переменные, то никакой области видимости не будет вообще, так как переменные могут быть достутны отовсюду Иначе мы можем вводить различные области видимости, в блоках и процедурах
my$sc_vr_1="ABC";# Идентификатор my перед объявлением перменной делает ее локальной, если объявить переменную с my в глобальной области видимости, то от этого она не станет глобальной (Конечно в плане обращения, к ней можно будет обратиться отовсюду, но правило перекрытия локальный перменных на нее будет действовать, и она уже не будет диманической)
{my$sc_vr_2=10;print$sc_vr_1;print$sc_vr_2;}# Создали блок, в Perl не обязательно связывть блок с if(1) {}, можно просто писать фигурные скобки Такая конструкция выведет ABC и 10
print$sc_vr_1;print$sc_vr_2;# Мы вышли из блока и локальная переменная удалилась, поэтому выведен ABC и undef
Однако в Perl помимо our и my, есть еще и local, предназначение которой на первой взгляд является немного странным, а именно при объявлении переменной как local идет работа с глобальной одноименной переменной, но значение глобальной переменной сохраняется Perlом в секретное место (В плане того что к старому значению, получить доступ нельзя), а по выходу из блока где была объявлена переменная local, глобальная переменная восстанавливает свое старое значение (Если ее ранее не было, то она получает значение undef)
Практическая пользя от local достагается только тогда, когда используется набор выполняемый процедур, где одна выполняет другую и при этом процедуры используют глобальные переменные В таком случае процерура, которая была вызвана более первой, может подменить значение глобальной переменной, и вызываемая ей функция будет использовать именно его Заметим, что в роли глобальной переменной может выступать и локальная, лишь бы она была определена в более главном блоке, и была полностью видема из процедур
my$sv=10;&sv1;# Локальная переменная, с фактически глобальной областью видимости, а также вызов первой процедуры
sub s1 {my$sv=20;print$sv;&s2;}# Первая процедура изменяет внутри себя переменную $sv (По правилу перекрытия локальных переменных), и будет выведено значение 20
sub s2 {print$sv;}# Вторая процедура видит глобальное значение $sv==10, и выведет именно 10
А теперь рассмотрим случай с local (Заметим что никакой странности в таком поведении нет, потому что в Perl нет параллельно-выполняющихся потоков, и всегда будет четко видно, изменена или не изменена ли переменная с помощью local)
my$sv=10;&s1;# Локальная переменная, с фактически глобальной областью видимости, а также вызов первой процедуры
sub s1 {local$sv=20;print$sv;&s2;}# Первая процедура фактически на время своего выполнения изменяет значение переменной $sv на 20, и поэтому будет выведено 20
sub s2 {print$sv;}# Вторая процедура видит глобальное значение $sv==20, и выведет 20
&s2;# А это вызов второй процедуры уже без влияний первой, соответсвенно будет выведено опять 10
To be continued...
----- Сделать можно все что угодно - нужно только старание, терпение и хороший поисковик
Безлимитный web-хостинг от 15 рублей за 40 МБ дискового пространства - http://ihost[dot]oks71[dot]ru/
movEAX
Отправлено: 13 Ноября, 2009 - 14:23:03
Частый посетитель
Покинул форум
Сообщений всего: 750
Дата рег-ции: Авг. 2009
Помог: 16 раз(а)
Хороший урок, но текст прям "месиво"))
----- армия.. самое убогое место
Ch_chov
Отправлено: 13 Ноября, 2009 - 14:33:09
Постоянный участник
Покинул форум
Сообщений всего: 2122
Дата рег-ции: Июль 2008 Откуда: из города
Покинул форум
Сообщений всего: 4350
Дата рег-ции: Авг. 2008 Откуда: Москва
Помог: 57 раз(а)
Ща буду вопросами тебя обсыпасть) С понедельника изучаю перл, надеюсь у тебя лучше получилось объяснить то, что я в других книжках не понял)
JustUserR
Отправлено: 13 Ноября, 2009 - 18:18:07
Активный участник
Покинул форум
Сообщений всего: 8715
Дата рег-ции: Июнь 2009
Помог: 17 раз(а)
Товарищи movEAX, Ch_chov - спасибо за отзывы и подсказку Champion - спасибо за отзыв, это хорошо что будешь вопросами осыпать, опробую свою консультацию на тебе
PS Урок еще не закончен, как написано внизу To be continued
----- Сделать можно все что угодно - нужно только старание, терпение и хороший поисковик
Безлимитный web-хостинг от 15 рублей за 40 МБ дискового пространства - http://ihost[dot]oks71[dot]ru/
EuGen
Отправлено: 14 Ноября, 2009 - 16:04:00
Профессионал
Покинул форум
Сообщений всего: 9095
Дата рег-ции: Июнь 2007 Откуда: Berlin
Помог: 707 раз(а)
Присоединюсь к обмену опытом, что-то наверное сам почерпну, чему-то смогу научить при необходимости
----- Есть в мире две бесконечные вещи - это Вселенная и человеческая глупость. Но насчет первой .. я не уверен.
Champion
Отправлено: 20 Ноября, 2009 - 16:36:53
Активный участник
Покинул форум
Сообщений всего: 4350
Дата рег-ции: Авг. 2008 Откуда: Москва
Помог: 57 раз(а)
JustUserR пишет:
напомню что двойные кавычки отличатся от одиночных наличием интерполяции (Подстановки переменных в них)
Наверное, это все-таки интерпретация.
Цитата:
Интерполяция в математике и статистике, отыскание промежуточных значений величины по некоторым известным её значениям
JustUserR
Отправлено: 21 Ноября, 2009 - 13:05:51
Активный участник
Покинул форум
Сообщений всего: 8715
Дата рег-ции: Июнь 2009
Помог: 17 раз(а)
Champion пишет:
Наверное, это все-таки интерпретация.
Может быть это неудачный термин, в связи с тем что в математике он означает другое, но всетаки это называется именно так - можете посмотреть оригинальную литературу, скажем Learning Perl или Programming Perl
Кстати в Perl не двойной интерполяции переменных, что означает то что если в строку интерполируетс другая строка, и эта другая строа содержит переменные, то они не будут интерполированы второй раз Таким образом, чтобы запртить интерполяцию переменных в строках, можно заместо имени строки $str в выражениях подстановки писать "$str" Хотя более верный вариант это одиночные кавычки
----- Сделать можно все что угодно - нужно только старание, терпение и хороший поисковик
Безлимитный web-хостинг от 15 рублей за 40 МБ дискового пространства - http://ihost[dot]oks71[dot]ru/
Champion
Отправлено: 17 Декабря, 2009 - 09:35:02
Активный участник
Покинул форум
Сообщений всего: 4350
Дата рег-ции: Авг. 2008 Откуда: Москва
Помог: 57 раз(а)
Может, я чересчур придираюсь, но захотел я на практике попрактиковаться, пощупать типы данных. А как? Где взять перл? Как оформить программу? Требую Hello World! (Добавление)
Хотя бы в самом начале что-то типа:
Все примеры вы можете попробовать у себя, ставим перл так-то отуда-то, пишем скрипт
Покинул форум
Сообщений всего: 8715
Дата рег-ции: Июнь 2009
Помог: 17 раз(а)
Champion пишет:
Может, я чересчур придираюсь, но захотел я на практике попрактиковаться, пощупать типы данных. А как? Где взять перл? Как оформить программу? Требую Hello World!
Хотя бы в самом начале что-то типа:
Все примеры вы можете попробовать у себя, ставим перл так-то отуда-то, пишем скрипт
Нет вы совершенно правы, я начал статью http://forum.php.su/topic.php?fo...m=65&topic=3 , где изложил теорию, как работает CGI и Perl в общем, чтобы стало понятнее В ближайшее время буду дописывать и пополнять
Буду раз любым комментариям и критике
----- Сделать можно все что угодно - нужно только старание, терпение и хороший поисковик
Безлимитный web-хостинг от 15 рублей за 40 МБ дискового пространства - http://ihost[dot]oks71[dot]ru/
Все гости форума могут просматривать этот раздел. Только зарегистрированные пользователи могут создавать новые темы в этом разделе. Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.