Zadania do wykładu o pakietach i modułach

Uniwersytet Gdański - Instytut Matematyki - Zakład Informatyki - Strona domowa

Perl: programowanie - pakiety i moduły

  1. Czy w jednym pliku perla można umieścić kilka różnych pakietów? Sprawdź.
    Oczywiście że można i dość często się tak robi przy definiowaniu pakietów prywatnych lub podklas. Jednym słowem, taki kod działa: package Zero; #.... package Jeden; #... package main; #... Aby stworzyć moduł, który korzysta z prywatnego pakietu, należy stworzyć plik o nazwie takiej jak główny pakiet, i w pliku tym umieścić główny pakiet oraz inne pakiety, których nie będzie można "zobaczyć" poza plikiem.
  2. Obejrzyj moduł o nazwie CGI::Apache (można go znaleźć na mancie za pomocą perldoc (oczywiście trzeba znać opcje tegoż). Fajny ten moduł... Niemniej jest to jakiś wzór gdyby trzeba było pisać własny.
    Oto treść tego modułu: use CGI; $VERSION = '1.00'; 1; __END__ =head1 NAME CGI::Apache - Backward compatibility module for CGI.pm =head1 SYNOPSIS Do not use this module. It is deprecated. =head1 ABSTRACT =head1 DESCRIPTION =head1 AUTHOR INFORMATION =head1 BUGS =head1 SEE ALSO =cut
  3. Stwórz pakiet o nazwie Dane (poprzez napisanie package Dane; i umieść w nim funkcję o nazwie Dane. Następnie w tym samym pliku przełącz się na pakiet main i sprawdź, czy istnieje coś takiego jak jakiś konflikt nazwy funkcji i pakietu w którym ona się znajduje. Spróbuj wywołać funkcję Dane z pakietu main.
    Kod który rozwiązuje to zadanie jest bardzo prosty: package Dane; sub Dane { print "jestem w funkcji Dane\n"; } package main; Dane(); Wykonanie tego kodu wywołuje błąd "Undefined subroutine &main::Dane called at Dane.pl line 6.". I słusznie - wołana jest funkcja Dane bez żadnej kwalifikacji pakietowej, stąd domyślnie perl przyjmuje że chodzi o nazwę main::Dane a takiej funkcji nie zdefiniowano. Aby kod działał, należy wywołać zamiast Dane, funkcję Dane::Dane. I to działa. Jak widać nie ma konfliktu nazwy pomiędzy pakietem, a funkcją.
  4. Napisz prosty moduł, w którym umieść funkcje do obliczania np. pierwiastków trójmianu kwadratowego. Moduł może nazywać się Trojmian. Następnie napisz krótki program testujący działanie funkcji z napisanego modułu. Uwaga: nie używaj żadnego importowania/eksportowania nazw. Po prostu wykorzystaj funkcje z napisanego przez siebie modułu.
    Oto kod takiego modułu: package Trojmian; use strict; sub _delta { my $a = shift; my $b = shift; my $c = shift; return $b*$b - 4*$a*$c; } sub x1 { my $a = shift; my $b = shift; my $c = shift; my $delta = _delta($a,$b,$c); if($delta > 0.0){ return 0.5*(-$b - sqrt($delta))/$a; } else{ return "NaN"; } } sub x2 { my $a = shift; my $b = shift; my $c = shift; my $delta = _delta($a,$b,$c); if($delta > 0.0){ return 0.5*(-$b + sqrt($delta))/$a; } else{ return "NaN"; } } 1; A oto przykładowy program, który z niego korzysta: #!/usr/bin/perl -wl use lib '.'; use Trojmian; print Trojmian::x1(1,1,-1); print Trojmian::x2(1,1,-1); Jak widać, moduł musi być zakończony jakimkolwiek wyrażeniem, które zwraca wartość "prawda". Tradycyjnie umieszcza się na końcu modułu liczbę 1, ale może to być także dowolna funkcja, która coś robi (np. inicjalizuje moduł). Wartość "fałsz" na obliczona na końcu modułu umiemożliwia jego załadowanie. W programie głównym ładujemy moduł przez use Trojmian; i wyliczamy wartości pierwiastków, wywołując funkcje Trojmian::x1 oraz Trojmian::x2.
  5. Sprawdź za pomocą perldoc jak zbudowany jest niewielki moduł o nazwie Locale::Constants (jeżeli nie znajdziesz go za pomocą perldoc, to znaczy, że moduł ten może nie zawierać dokumentacji. Przeszukaj wtedy wszystkie katalogi, które są wpisane w zmienną @INC w perlu, to na pewno go znajdziesz). Na podstawie tego modułu spróbuj napisać własny moduł o nazwie Viggo::Brun, który w pakiecie wywołującym udostępni dwie stałe Bruna o nazwach B2 (nie mylić z witaminą B2) i B4. Napisz też program o takiej postaci: use strict; use lib '.'; # scieżka do twojego modułu use Viggo::Brun; # załadowanie modułu printf "%10.7f %10.7f\n", B2, B4; W programie tym nie może być żadnego błędu. Wszystko oczywiście zależy od tego, JAK napiszesz moduł Viggo::Brun, i o to właśnie chodzi.
    Oto treść modułu Locale::Constants. Jak widać, moduł ten ma ładną, szablonową konstrukcję, którą można wykorzystać do zrobienia modułu Viggo::Brun. # Locale::Constants - defined constants for identifying codesets # # $Id: Constants.pm,v 2.7 2004/06/10 21:19:34 neilb Exp $ # package Locale::Constants; use strict; require Exporter; #----------------------------------------------------------------------- # Public Global Variables #----------------------------------------------------------------------- use vars qw($VERSION @ISA @EXPORT); $VERSION = sprintf("%d.%02d", q$Revision: 2.7 $ =~ /(\d+)\.(\d+)/); @ISA = qw(Exporter); @EXPORT = qw(LOCALE_CODE_ALPHA_2 LOCALE_CODE_ALPHA_3 LOCALE_CODE_NUMERIC LOCALE_CODE_DEFAULT); #----------------------------------------------------------------------- # Constants #----------------------------------------------------------------------- use constant LOCALE_CODE_ALPHA_2 => 1; use constant LOCALE_CODE_ALPHA_3 => 2; use constant LOCALE_CODE_NUMERIC => 3; use constant LOCALE_CODE_DEFAULT => LOCALE_CODE_ALPHA_2; 1; Tworzenie modułu Viggo::Brun należy zacząć od zaobserwowania, że moduł ten posiada nazwę złożoną z słowa Viggo oraz ze słowa Brun. Oczywiście nie będziemy robić nazwy pliku Viggo::Brun.pm, ponieważ dwukropek nie jest polecanym znakiem do użycia w nazwach plików, a w niektórych systemach znak ten jest zabroniony. W perlu takie złożone nazwy modułów oznaczają tylko tyle, że dany moduł nazywa się tak jak ostatni człon w nazwie, natomiast sam plik jest umieszczony w katalogach o nazwach takich jak pierwsze człony nazwy. Czyli w tym przypadku nasz moduł musi być w pliku Brun.pm, a plik ten położony musi być w katalogu Viggo. Treść modułu jest bardzo prosta, wystarczy napisać: package Viggo::Brun; use vars qw(@ISA @EXPORT); @ISA = qw(Exporter); @EXPORT = qw(B2 B4); use constant B2 => 1.902160583104; use constant B4 => 0.8705883800; 1; Kod programu, który wykorzystuje ten moduł do wyświetlenia wartości stałych może wyglądać tak: #!/usr/bin/perl -wl use lib '.'; use Viggo::Brun; print B2; print B4; Jednakże kod źródłowy modułu Locale::Constants nie jest najnowszy i zawiera konstrukcje charakterystyczne dla perla 5.6 i starszych wersji. W wersji 5.8 możemy napisać trochę nowocześniejszy kod, i zarazem kod krótszy: package Viggo::Brun; use strict; use base 'Exporter'; # dziedziczymy po module Exporter pewne ukryte własności our @EXPORT = qw(B2 B4); use constant B2 => 1.902160583104; use constant B4 => 0.8705883800; 1;
Uniwersytet Gdański - Instytut Informatyki - Strona domowa - Perl - Zadania
[c] Piotr Arłukowicz, materiały z tej strony udostępnione są na licencji GNU.