Основи Perl - use strict, посилання та функції, Записки програміста
Основи Perl - use strict, посилання та функції
Третя частина циклу статей, присвячених основам програмування на Perl. Якщо ви пропустили перші дві частини, ознайомтеся із змістом.
Директива use strict
$ alpha = 1; $ beta = 2; #. $alpha = $alpha + $beta; # alpha дорівнює 3
Однак що станеться, якщо ми випадково зробимо друкарську помилку в імені однієї зі змінних?
Програміст допускає подібні помилки досить часто — частіше, ніж багато хто думає. При цьому, через друкарську помилку в імені однієї змінної, поведінка програми може змінюватися зовсім несподіваним чином. Зайві ітерації циклів, висновок повідомлень, яких, здавалося б, скрипт ніяк не повинен був виробляти — лише мала частина списку можливих «побічних ефектів». Зазвичай виправлення таких помилок — справа непроста, адже програміст починає шукати їх з кінця, з того місця, де програма повелася неправильно. Тобто там, де помилок насправді немає.
#/usr/bin/perl use strict;
my $ alpha = 1; my $beta = 2; #. $alpha = $alpha + $beta; # alpha дорівнює 3
Зовсім не складно, правда? Що ж станеться, якщо ми зробимо друкарську помилку в імені змінної? Оскільки змінна $bata раніше не була оголошена, інтерпретатор лаятиметься на синтаксичну помилку і скрипт просто не виконається, поки ми не виправимо помилку.
Ще раз повторюю — при написанні скрипта, розміром більше 10 рядків коду, завжди використовуйте директиву use strict . В іншому випадку ви ризикуєте витратити багато часу на виправлення абсолютно «містичних» помилок.
Пам'ятайте, у першій частині «основ Perl» ми використовували масиви та хеші. Цікавий читач запитає — а як бути з багатовимірними масивами, масивамихешів та іншими складними структурами? Невже Perl не підтримує їх? Насправді це не так, і скоро ви в цьому переконаєтесь.
Спочатку розглянемо просте завдання — оголосити двовимірний масив. Ось один із способів це зробити:
my @ arr1 = (1, 2, 3); my @ arr2 = (4, 5, 6); my @ arr3 = (7, 8, 9);
my @ matrix = ( @ arr1 , arr2 , arr3 ) ;
for ( my $i = 0 ; $i 3 ; $i ++ ) < for ( my $j = 0 ; $j 3 ; $j ++ ) < print $matrix [$i] [$j]. ""; > print "\n"; >
Тут було оголошено масив із трьох елементів @matrix, елементами якого є посилання масиви @arr1, @arr2 і @arr3. Дивіться, що відбувається - в масиві як і раніше зберігаються скаляри, але оскільки вони, ці скаляри, є посилання на масиви, ми фактично маємо справу з багатовимірним масивом!
Як ви вже могли здогадатися, отримання посилання на змінну відбувається за допомогою оператора «зворотний слеш»:
Інший спосіб отримати посилання на масив - використовувати квадратні дужки:
Аналогічний спосіб отримати посилання на хеш – використовувати фігурні дужки:
# використовуємо оператор "стрілка" print $aref2 -> [0]. "\n"; # виведе 4 print $href -> < aaa >. "\n"; # виведе 7
Враховуючи все сказане вище, давайте спробуємо попрацювати з двовимірним масивом і масивом, елементами якого є хеші.
my @ matrix = (# оголошуємо масив [1, 2, 3], # елементи якого - посилання на масив [4, 5, 6], [7, 8, 9]);
print $matrix [0] -> [1]. "\n"; # виведе 2 print $ matrix [2] [2]. "\n"; # виведе 9, "стрілку" можна опустити
my @points = ( # масив точок < x =>7 , y => 13 > , < x =>- 3 , y=> 2 > , < x =>0 , y => - 9 > );
координати першої точки print $points [ 0 ] -> < x >. ";" . $points [ 0 ] -> < y >. "\n";
# координати другої точки # аналогічно попередньому прикладу - оператор "стрілка" можна опустити print $points [1] < x >. ";" . $points [ 1 ] < y >. "\n";
Оператор стрілка завжди можна опускати між індексами. Тобто наступні два рядки коду абсолютно аналогічні:
Посилання та витік пам'яті
@arr = undef; # аналогічно виклику undef() у PHP
print $arr_ref -> [1]. "\n"; # виведе 5! # ^ тут, до речі, "стрілку" опустити не можна # інакше Perl вирішить, що ми працюємо з # не оголошеною змінною @arr_ref
$arr_ref = undef; # ось тільки тепер пам'ять, виділена під # безіменний масив (4, 5, 6) буде звільнено
Особливо важливо пам'ятати про це під час роботи зі структурами типу дерев та двозв'язних списків. Якщо вчасно не звільнити виділену під них пам'ять, є шанс, що пам'яті не вистачить і скрипт аварійно завершиться.
#!/usr/bin/perl use strict;
sub myfunc < my ($ alpha, $ beta) = @_; $alpha + $beta; >
print myfunc (2, 3). "\n";
Результат останньої операції, виконаної всередині функції, буде повернено як результат. За допомогою оператора return можна повернути результат у довільному місці функції, не тільки наприкінці:
#!/usr/bin/perl use strict;
sub myfunc < my ($ alpha, $ beta) = @_; if ( $alpha > $beta ) < # припинити виконання функції та повернути результат return $alpha - $beta ; > $beta - $alpha; >
print myfunc (2, 3). "\n";
Як бачите,для передачі аргументів функції, використовується спеціальна змінна @_. Якщо як аргумент необхідно передати масив або хеш, використовуйте посилання. Пам'ятайте, що в цьому випадку відбувається передача аргументу за посиланням, а не за значенням:
#!/usr/bin/perl use strict;
sub setval < my ($ ref, $ val) = @_; $ref -> < val >= $val ; >
my %hash; setval (% hash, 14); print "$hash \n"; # виведе 14
Думаю, на сьогодні це все. У наступних частинах я розповім про роботу з файлами, глоби, функції eval і system, операторів sort і grep (як з'ясувалося, наступний урок і так виявився дуже об'ємним, тому закреслене в нього не увійшло). Регулярні вислови, швидше за все, не увійдуть до «основ Perl» — за бажання цього питання можна присвятити окрему статтю, якщо не серію статей.
Якщо є питання – ставте. Щоб не пропустити нові матеріали, слідкуйте за оновленнями блогу через RSS або Twitter. Успіхів у вивченні Perl!