September 2008 Archive

Das CPAN-Modul Devel::Size beantwortet die Frage nach dem Speicherverbrauch (RAM) einer Perl-Datenstruktur.

Devel::Size exportiert zwei Funktionen: size() und total_size().

size() ermittelt die Größe der Datenstruktur in Bytes ohne den Inhalt der Datenstruktur.

total_size() ermittelt die Größe der Datenstruktur in Bytes unter Berücksichtigung des Inhalts der Datenstruktur.

Beide Funktionen erwarten eine Referenz (\) auf die Datenstruktur als Parameter.

Beispiel:

#!/usr/bin/perl 
use strict;
use warnings;

use Devel::Size qw(size total_size);

my $string = '1234567890';

print 'Size string:      ' , size(\$string)       ,"\n"; 
print 'TotalSize string: ' , total_size(\$string) , "\n"; 
print "\n";

my @array = qw( 1 2 3 4 5 6 7 8 9 0);

print 'Size array:       ' , size(\@array)       , "\n"; 
print 'TotalSize array:  ' , total_size(\@array) , "\n"; 
print "\n";

my %hash = ( 1 => 1, 2 => 2, 3 => 3,
             4 => 4, 5 => 5, 6 => 6,
             7 => 7, 8 => 8, 9 => 9, 0 => 0);

print 'Size hash:        ' , size(\%hash)       , "\n"; 
print 'TotalSize hash:   ' , total_size(\%hash) , "\n"; 
print "\n";

      # Array of Arrays
my @AoA = (
        [ "fred", "barney" ],
        [ "george", "jane", "elroy" ],
        [ "homer", "marge", "bart" ],
      );

print 'Size AoA:         ' , size(\@AoA)       , "\n"; 
print 'TotalSize AoA:    ' , total_size(\@AoA) , "\n"; 

Das Programm erzeugt folgende Ausgabe:

Size string:      36
TotalSize string: 36

Size array:       96
TotalSize array:  376

Size hash:        354
TotalSize hash:   514

Size AoA:         72
TotalSize AoA:    576

Siehe auch

Das ZIP-Dateiformat ist ein offenes Format zur komprimierten Archivierung von Dateien. Neben mehreren Dateien können auch ganze Verzeichnisbäume in einer einzelnen ZIP-Datei archiviert und komprimiert werden.

Archive::Zip von Adam Kennedy ermöglicht das Erstellen und Entpacken von Zip-Archiven

Die Handbuchseite zu Archive::Zip ist ziemlich verwirrend. Glücklicherweise befinden sich in der Source-Code Distribution (Archive-Zip-1.23.tar.gz) im Ordner examples zahlreiche Beispiele zur Verwendung von Archive::Zip, von denen ich hier zwei vorstelle:

Verzeichnisse und Dateien zippen

Das Beispielprogramm zip.pl aus dem examples Verzeichnis ist genau das gewünschte Tool.

zip.pl

#!/bin/perl -w
# Creates a zip file, adding the given directories and files.
# Usage:
# perl zip.pl zipfile.zip file [...]

use strict;
use Archive::Zip qw(:ERROR_CODES :CONSTANTS);

die "usage: $0 zipfile.zip file [...]\n"
 if (scalar(@ARGV) < 2);

my $zipName = shift(@ARGV);
my $zip = Archive::Zip->new();

foreach my $memberName (map { glob } @ARGV)
{
 if (-d $memberName )
 {
  warn "Can't add tree $memberName\n"
   if $zip->addTree( $memberName, $memberName ) != AZ_OK;
 }
 else
 {
  $zip->addFile( $memberName )
   or warn "Can't add file $memberName\n";
 }
}

my $status = $zip->writeToFileNamed($zipName);
exit $status;

Anwendungsbeispiele:

Komplettes Verzeichnis zippen

perl zip.pl test.zip examples

oder auch

perl zip.pl test.zip examples/*

Einzelne Dateien zippen

perl zip.pl test.zip datei1.doc datei2.doc dateiN.doc

Zip-Dateien entpacken

Auch hier findet man das gewünschte Tool als Beispielprogramm unzipAll.pl im examples Verzeichnis.

unzipAll.pl

#!/bin/perl -w
# Extracts all files from the given zip
# $Revision: 1.3 $
# usage:
#	perl unzipAll.pl [-j] zipfile.zip
# if -j option given, discards paths.
#
use strict;

use vars qw( $opt_j );
use Archive::Zip qw(:ERROR_CODES);
use Getopt::Std;

$opt_j = 0;
getopts('j');

if (@ARGV < 1)
{
	die <<EOF
	usage: perl $0 [-j] zipfile.zip
	if -j option given, discards paths.
EOF
}

my $zip = Archive::Zip->new();
my $zipName = shift(@ARGV);
my $status = $zip->read( $zipName );
die "Read of $zipName failed\n" if $status != AZ_OK;

$zip->extractTree();

Anwendungsbeispiel:

$ perl unzipAll.pl X.zip

Known Bugs

Mit Archive::Zip erstellte Archive lassen sich nicht immer mit Windows-Bordmitteln öffnen. Die Behebung dieses Fehlers ist derzeit in Arbeit. Achten Sie ggf. auf neuere Versionen.

Siehe auch:

alexm hat drüben bei den Perlmonks ein kleines Programm zur tagesaktuellen Währungsumrechnung veröffentlicht: Using up-to-date currency conversion rates

#!/usr/bin/perl 
use strict;
use warnings;


# Quelle: Using up-to-date currency conversion rates
# http://www.perlmonks.org/?node_id=709343

use Locale::Currency;
use File::Basename;
use Cache::FileCache;
use Finance::Quote;

die "usage: $0 amount currency_from currency_to\n"
    unless @ARGV == 3;

my $amount = shift @ARGV;

my ($currency_from, $currency_to) = map { uc } @ARGV;

for my $code ($currency_from, $currency_to) {
    die "sorry, currency $code not in ISO 4217\n"
        unless defined code2currency($code);
}

my ($filename) = fileparse($0, '.pl');

my $cache = Cache::FileCache->new({
    cache_root         => "$ENV{HOME}/.$filename",
    default_expires_in => '1 day',
});

my $quote = Finance::Quote->new();

my $ratio = $cache->get("$currency_from:$currency_to");

$ratio = $quote->currency($currency_from, $currency_to)
    unless defined $ratio;

die "sorry, cannot convert from $currency_from to $currency_to\n"
    unless defined $ratio;

$cache->set("$currency_from:$currency_to", $ratio);
print "$amount $currency_from = ", $amount * $ratio, " $currency_to\n";

Wenn man das Programm als currency.pl speichert und anschließend auf der Kommandozeile aufruft, ergibt sich beispielsweise folgende Ausgabe.

$ perl currency.pl 100 USD EUR
100 USD = 70.46 EUR

Finance::Quote holt den Umrechnungsfaktor, Cache::FileCache speichert diesen Faktor für einen Tag auf der lokalen Festplatte und Locale::Currency prüft, ob die eingegebenen Währungscodes gültig sind.

Siehe auch:

ISO 4217 ist die von der Internationalen Organisation für Normung publizierte Norm für Währungs-Abkürzungen, die im internationalen Zahlungsverkehr zur eindeutigen Identifizierung benutzt werden sollen.

Locale::Currency von Neil Bowers ermöglicht den Zugriff auf die drei Buchstaben langen Abkürzungen (ISO-Codes). Der Zugriff auf die numerischen Währungscodes ist nicht implementiert.

Mit Hilfe dieses Moduls lässt sich z.B. leicht prüfen, ob ein gültiger ISO-Code vorliegt.

#!/usr/bin/perl
use strict;
use warnings;

use Locale::Currency;

$| = 1;    # turn off buffering

print Bitte Währungscode eingeben: ";
chomp(my $code = <STDIN>);

my $curr = code2currency($code);

if (defined $curr) {
        print "$code = $curr\n";
}
else {
        print "'$code' ist kein gültiger Währungscode!\n";
}

Wenn man das Programm als localecurrency.pl speichert und anschließend auf der Kommandozeile aufruft, ergibt sich beispielsweise folgende Ausgabe.

$ perl localecurrency.pl 
Bitte Währungscode eingeben: EUR
EUR = Euro

$ perl localecurrency.pl 
Bitte Währungscode eingeben: USD
USD = US Dollar

$ perl localecurrency.pl 
Bitte Währungscode eingeben: XYZ
'XYZ' ist kein gültiger Währungscode!

Weiterhin kann aus dem Namen der Währung der ISO-Code ermittelt werden.

#!/usr/bin/perl
use strict;
use warnings;

use Locale::Currency;

$| = 1;    # turn off buffering

print "Bitte Währungsname eingeben: ";
chomp(my $currency = <STDIN>);

my $code = currency2code($currency);

if (defined $code) {
        print "$currency = $code\n";
}
else {
        print "'$currency' ist kein gültiger Währungsname!\n";
}

Wenn man das Programm als localecurrency2.pl speichert und anschließend auf der Kommandozeile aufruft, ergibt sich beispielsweise folgende Ausgabe.

$ perl localecurrency2.pl
Bitte Währungsname eingeben: EURO
EURO = eur

$ perl localecurrency2.pl
Bitte Währungsname eingeben: USD
'USD' ist kein gültiger Währungsname!

$ perl localecurrency2.pl
Bitte Währungsname eingeben: US Dollar
US Dollar = usd

Siehe auch

Die ISO 3166 ist ein Standard für die Kodierung von geographischen Einheiten, aka Ländern. Jedem Land werden drei Codes zugeordnet: Ein zweistelliger Ländercode (ALPHA-2), ein dreistelliger Ländercode (ALPHA-3) und ein numerischer Ländercode (NUMERIC).

Diese Ländercodes können in der ISO-3166-1-Kodierliste nachgeschlagen werden. Beispielsweise sind Deutschland (Germany) folgende Codes zugeordnet:

  • DE (ALPHA-2)
  • DEU (ALPHA-3)
  • 276 (NUMERIC)

Locale::Countryvon Neil Bowers ermöglicht den Zugriff auf die Ländercodes gemäß ISO 3166.

Über die der Konstanten LOCALE_CODE_ALPHA_2, LOCALE_CODE_ALPHA_3 und LOCALE_CODE_NUMERIC teilt man den Funktionen code2country() bzw. country2code() mit, welcher der drei Codes verwendet werden soll. Ohne diese Angabe wird automatisch LOCALE_CODE_ALPHA_2 verwendet.

Mit Hilfe dieses Moduls lässt sich z.B. leicht prüfen, ob ein gültiger ISO-Code vorliegt.

#!/usr/bin/perl 
use strict;
use warnings;

use Locale::Country;

$| = 1;    # turn off buffering

###########################################################
print "Bitte zweistelligen Ländercode eingeben: ";
chomp(my $code = <STDIN>);

my $country = code2country($code); # LOCALE_CODE_ALPHA_2 implizit
if (defined $country) {
        print "$code = $country\n";
}
else {
        print "'$code' ist kein gültiger Ländercode!\n";
}
###########################################################
print "Bitte dreistelligen Ländercode eingeben: ";
chomp($code = <STDIN>);

$country = code2country($code, LOCALE_CODE_ALPHA_3); 
if (defined $country) {
        print "$code = $country\n";
}
else {
        print "'$code' ist kein gültiger Ländercode!\n";
}
###########################################################
print "Bitte dreistelligen numerischen Ländercode eingeben: ";
chomp($code = <STDIN>);

$country = code2country($code, LOCALE_CODE_NUMERIC); 
if (defined $country) {
        print "$code = $country\n";
}
else {
        print "'$code' ist kein gültiger Ländercode!\n";
}
###########################################################

Wenn man das Programm als localecountry.pl speichert und anschließend auf der Kommandozeile aufruft, ergibt sich beispielsweise folgende Ausgabe.

per localecountry.pl 
Bitte zweistelligen Ländercode eingeben: DE
DE = Germany
Bitte dreistelligen Ländercode eingeben: DEU
DEU = Germany
Bitte dreistelligen numerischen Ländercode eingeben: 276
276 = Germany

Aus dem Namen eines Landes lassen sich leicht die zugehörigen Ländercodes ermitteln. Gleichzeitig lässt sich prüfen, ob der Name des Landes der ISO 3166 entspricht.

#!/usr/bin/perl 
use strict;
use warnings;

use Locale::Country;

$| = 1;    # turn off buffering

print "Bitte den Namen eines Landes eingeben: ";
chomp(my $country = <STDIN>);

my $code    = country2code($country); # LOCALE_CODE_ALPHA_2 implizit
if ( defined $code ) {
	print "$country = $code\n";
} 
else {
	print "'$country' ist kein gültiger Name!\n";
	exit;
}

$code    = country2code($country, LOCALE_CODE_ALPHA_3 );    
print "$country = $code\n";

$code    = country2code($country, LOCALE_CODE_NUMERIC );    
print "$country = $code\n";

Wenn man das Programm als localecountry2.pl speichert und anschließend auf der Kommandozeile aufruft, ergibt sich beispielsweise folgende Ausgabe.

perl localecountry2.pl 
Bitte den Namen eines Landes eingeben: Germany
Germany = de
Germany = deu
Germany = 276

Siehe auch

Über dieses Archiv

Diese Seite enthält alle Einträge von Perl HowTo von neu nach alt.

August 2008 ist das vorherige Archiv.

November 2008 ist das nächste Archiv.

Aktuelle Einträge finden Sie auf der Startseite, alle Einträge in den Archiven.

Fachzeitschriften

Blog Roll

Powered by

Powered by Movable Type 5.2.10

Creative Commons-Lizenz

Creative Commons License
Dieses Weblog steht unter einer Creative Commons-Lizenz.