[gull] Faut-il réhabiliter Perl comme langage de scripting système?
Marc SCHAEFER
schaefer at alphanet.ch
Fri Mar 9 10:04:18 CET 2018
Hello,
Perl laisse le choix, par exemple le code suivant:
$ cat a.pl
#! /usr/bin/perl
my $data = "toto";
print $date, "\n";
$ ./a.pl
avec les warnings:
$ perl -w a.pl
Name "main::date" used only once: possible typo at a.pl line 5.
Use of uninitialized value $date in print at a.pl line 5.
avec use strict:
$ ./a.pl
Global symbol "$date" requires explicit package name at ./a.pl line 7.
Execution of ./a.pl aborted due to compilation errors.
On Thu, Mar 08, 2018 at 12:25:36PM +0100, Laurent Franceschetti wrote:
> raison valable de se compliquer la vie.
man perl
Using the "use strict" pragma ensures that all variables are properly
declared and prevents other misuses of legacy Perl features.
The "use warnings" pragma produces some lovely diagnostics. One can
also use the -w flag, but its use is normally discouraged, because it
gets applied to all executed Perl code, including that not under your
control.
En ce qui me concerne, je trouve le risque de n'être pas informé
de ce genre d'erreurs plus grave que d'écrire 2 lignes systématiquement
dans mes scripts Perl.
Après, il y a aussi le style de programmation, comparer:
#! /usr/bin/perl
use strict;
use warnings;
my %data = ('un' => 'bla', 'deux' => 'toto');
print $data{'deux'},
$data{'uns'}, # <-- ici un warning, bien
"\n";
$data{'uns'} = 'toto'; # <-- ici pas de warning, clé 'uns' créée alors
# que je voulais réellement mettre à jour
# 'un'
# NB: en Perl on peut aussi écrire $data{uns} sous certaines conditions,
# mais je ne préfère pas.
avec:
#! /usr/bin/perl
use strict;
use warnings;
my $data = new data;
# setters
$data->un("new value");
$data->deux("new value 2");
# getters $obj->nom ou $obj->nom()
print join("\n", $data->un, $data->deux(), "");
# print $data->uns; # <-- ici erreur, bien (un peu comme avant)
$data->uns("new value"); # <-- ici erreur, mieux qu'avant
package data;
use strict;
use warnings;
use parent 'Class::Accessor::Fast';
BEGIN {
__PACKAGE__->mk_accessors(qw/un deux/);
}
sub new {
my $class = shift;
return $class->SUPER::new();
}
Après, je dois avouer que je fais rarement ce genre d'erreurs, donc j'utilise
rarement ça, d'un autre côté, avec la vue qui baisse avec l'âge ...
NB: pour de l'OO encore plus moderne, par exemple (exemple de la manpage Moose)
package Point;
use Moose; # automatically turns on strict and warnings
has 'x' => (is => 'rw', isa => 'Int');
has 'y' => (is => 'rw', isa => 'Int');
sub clear {
my $self = shift;
$self->x(0);
$self->y(0);
}
package Point3D;
use Moose;
extends 'Point';
has 'z' => (is => 'rw', isa => 'Int');
after 'clear' => sub {
my $self = shift;
$self->z(0);
};
J'ai un peu joué avec Moose, mais ce n'est pas ma façon de
faire du Perl, c'est trop haut niveau :->
En ce qui me concerne, si j'utilise souvent du code qui fait
usage de ce genre de chose ou approchant (style l'autoparseur
de DB existante qui génère les classes ORM automatiquement,
complété ci-dessous par une requête complexe manuelle
# http://search.cpan.org/dist/DBIx-Class/lib/DBIx/Class/Manual/Cookbook.pod
# http://stackoverflow.com/questions/8939475/dbix-and-arbitrary-sql-through-a-custom-resultsource
package get_services_complex_query;
use strict;
use warnings;
use base 'DBIx::Class::Core';
__PACKAGE__->table("dummy");
__PACKAGE__->add_columns('name');
__PACKAGE__->result_source_instance->name(\'(
SELECT p.name
FROM proto p, source_fetch of, source_fetch_content ofc, source_fetch_content_data ofcd, source o
WHERE (p.id = ofcd.proto) AND (of.id = ofc.source_fetch) AND (of.source = o.id) AND (o.id = ?)
)');
1;
# generate classes at runtime from the DB schema
# see qw/DBIx::Class::Schema::Loader
package schema;
use base qw/DBIx::Class::Schema::Loader/;
__PACKAGE__->loader_options(
);
__PACKAGE__->register_class(get_services_complex_query => 'get_services_complex_query');
1;
Qu'on utilise ensuite ainsi:
my $dbi = schema->connect($CFG::config{'dbi_dsn'},
$CFG::config{'dbi_user'},
$CFG::config{'dbi_pass'},
{ RaiseError => 1, AutoCommit => 1 });
my $o = $dbi->resultset('Services')->find({name => $service});
my @r = $dbi->resultset('get_services_complex_query')
->search({},
{bind => [ $o->id ]});
return map { $_->name } @r;
)
je suis plus `manuel' dans mon code Perl. Question de goût.
More information about the gull
mailing list