Affichage des articles dont le libellé est Perl. Afficher tous les articles
Affichage des articles dont le libellé est Perl. Afficher tous les articles

28 décembre 2024

isPrime(n) avec une regex

Ce minuscule script Perl d'une seule instruction ( print str =~ regex ? no : yes ) indique par YES ou NO si le l'entier passé en argument sur la ligne de commande est un nombre premier :

#!/usr/bin/perl
#usage: isPrime.pl <entier>
print (('@' x $ARGV[0]) =~ /^.?$|^(..+?)\1+$/ ? "NO\n" : "YES\n");

Spirale d'Ulam

Le cœur du script est une expression régulière qui matche quand l'argument n'est pas un nombre premier. Cette expression régulière s'applique à une chaîne de caractères identiques et de longueur égale à la valeur de l'argument. 

La chaîne contenant autant de @ qu'indiqué par l'argument est construite avec  ('@' x $ARGV[0]).

Exemple: isPrime.pl 6  travaille sur la chaîne "@@@@@@"

La première partie de la regex ^.?$ détermine s'il y a 0 ou 1 caractère dans la chaîne, autrement dit si le nombre à tester est 0 ou 1. Si c'est le cas le nombre n'est pas premier (affiche NO).

La deuxième partie de la regex ^(..+?)\1+$ détermine s'il est possible de décomposer la chaîne en la répétition d'une sous chaîne d'au moins 2 caractères. Si c'est le cas c'est que la longueur de la chaîne (donc la valeur de l'argument) peut s’écrire L * N, (avec L>0 et N>1) et donc le nombre n'est pas premier (affiche NO).

  • L est la longueur de (..+?)
  • n est le valeur que représente le + dans \1+

Exemples :

  • isPrime.pl 9
    La chaîne de 9 caractères "@@@@@@@@@" est décomposée en 3 répétitions de "@@@"
    ==> matche ==> 9 n'est pas un nombre premier.

  • isPrime.pl 12
    La chaîne de 12 caractères "@@@@@@@@@@@@" est décomposée en 6 répétitions de "@@"
    ==> matche ==> 12 n'est pas un nombre premier.

  • isPrime.pl 11
    La chaîne de 11 caractères "@@@@@@@@@@@" n'est pas décomposable en N répétitions d'une chaîne de longueur L
    ==> ne matche ==> 11 est un nombre premier.

La classique boucle de cherche les diviseurs d'un nombre est prise en charge par la recherche itérative d'une solution dans le moteur d'expressions régulières. Bien sur la méthode n'est ni efficace en place mémoire ni en temps de calcul, mais elle est originale.

Vous trouverez une liste des 50000 premiers nombres premiers ici.

Note: L'image utilisée pour illustrer ce post est la spirale d'Ulam qui représente la position des nombres premiers sur une spirale. Les lignes droites semblent indiquer une certaine organisation (un pattern) des nombres premiers...intriguant...


01 janvier 2023

Perl 5 Search Engine

The Perl 5 search engine
Note: StackOverflow is excluded from the list of sites.
 
See also:  Download  Core modules  PerlDoc 

 

 

--- Ajouter ce search engine à Firefox ---

26 août 2018

Perl 6 n’est pas le successeur de Perl 5.

Perl 6 n’est pas le successeur de Perl 5. Qu’on se le dise !

UPDATE nov/2019: Le nom  Perl 6  est abandonné, le nouveau langage s’appelle maintenant  Raku.

Habituellement quand on incrémente le numéro de version c’est qu’il y a d’importantes nouveautés  mais la compatibilité ascendante est préservée. C’est le cas pour tous les langages honnêtes que je connais  C, C++, Java, JavaScript, Python, Pascal, PHP, Fortran, Cobol etc…

Mais le code source Perl 5 ne s’exécute pas sous Perl 6. Un seul exemple :
if(a==0){ ... }
 ne marche pas en Perl 6 à cause de l’absence d’espace entre if et la parenthèse ouvrante.

Quelques autres exemples :
  • En Perl 6 on écrit %liste<key> = 0; mais en  Perl 5 on écrit $liste{key} = 0; Notez bien les deux différences.
  • En Perl 6 l’opérateur de correspondance est ~~ en Perl 5 c’est =~
  • En Perl 6 l’operateur de concaténation est le tilde (~) en Perl 5 c’est le point (.)
  • L’operateur << devient +<
  • for devient loop, eval devient try.
  • ect ect ect La liste des differences est très longue.
En fait il y a autant de ressemblances entre C++ et Java qu’entre Perl 5 et Perl 6 : On reconnaît des points communs de syntaxe, on distingue certains concepts communs mais ce n’est pas la même chose.

Alors pourquoi pas un autre nom que Perl 6 ?

Je pense que les langages étant tellement nombreux actuellement, qu’un nouveau nom passerait totalement inaperçu. Il est très difficile de se faire une place entre le C# de Microsoft, le Go de Google, le Swift d’Apple sans oublier les vénérables PHP, Python, Java, C/C++. En gardant le nom Perl ils espèrent garder l’attention de la communauté Perl 5 et essayer de la convertir à Perl 6. Pour le moment ça ne marche pas. (à mon avis ça ne marchera jamais), il y a même des tensions entre les deux communautés. Il y a même des tensions à l’intérieur de Perl 6 entre Parrot (une des machine virtuelle supportant Perl 6) et Rakudo (le compilateur Perl 6 le plus connu).

Le plus stupide dans cette dénomination c'est que Perl 5 ne peut pas passer à la version suivante car il y aurait confusion entre le Perl 6/dromadaire et le Perl 6/papillon.
Perl 6/papillon, va rester à la version 6 pour toujours ?

J’ai commencé à apprendre tout en utilisant de manière professionnelle Perl 5, et exclusivement Perl 5. Eh bien je pense que connaître Perl 5 n’est pas un avantage décisif dans l’apprentissage de Perl 6. J’ai beaucoup perdu de temps en cherchant des ponts entre les deux soi-disant versions de Perl. En fait j’aurais gagné beaucoup de temps si j’étais parti dans l’optique d’apprendre un nouveau langage (un de plus !)

Note : Les performances ne sont pas (encore) au rendez-vous. On nous répète que le langage est jeune mais que ça va venir, qu'il y a des optimisation possibles. Mais on nous répète cela depuis 2015...

Packages

Si vous trouvez que votre distribution n'est pas assez réactive aux mises à jour de Rakudo (ou que Rakudo fait trop souvent des mises à jour ...), vous pouvez ajouter le repository raduko-pkg et bénéficier des mises à jour au fil de l'eau.


A suivre le blog de Jonathan Worthington, l’architecte de Rakudo (le compilateur Perl 6) et de MoarVM (la machine virtuelle de Perl 6)

Parodies




12 mars 2015

mod_perl 2.0.9

La version très attendue de mod_perl 2.0.9 fonctionnera avec pratiquement toutes les versions du serveur http 2.0.x, 2.2.x et 2.4.x d'Apache. C'est le support de 2.4.x qui est attendu depuis des années ! Ceci est d'autant plus important que CentOS 7 n'existe qu'en 64 bits et ne fournit que Apache 2.4. Pour utiliser mod_perl2 il fallait rester à Centos 6.x :-(

[ UPDATE: La version officielle de mod_perl 2.0.9 est disponible depuis le 18/juin/2015 ]
[ Mais en attendant les packages officiels la procédure ci-dessous reste valide ]

Steve Hay, le principal développer de mod_perl2, affirme que l'on est en phase de test ...
En attendant un package voici pour les impatients comment tester sous Linux (dans mon cas Centos 7) cette version bêta de mod_perl 2.0.9 (il y a encore quelques problèmes sous Windows, et Perl 5.22 n'est pas supporté).

# Il faut avoir de quoi compiler et bien-sur apache et ses fichiers de développement
yum group install "Development Tools"
yum install httpd httpd-devel

# Depuis le 19/juin/2015 on peut récupérer les sources ici
http://apache.org/dist/perl/

# Sinon on peut récupérer les source via SVN
svn checkout https://svn.apache.org/repos/asf/perl/modperl/trunk/ mod_perl-2.0.9

# Il ne faut pas etre root sinon le 'make test' echoue
# On prepare un Makefile, on compile, on teste
# Vérifier que /usr/bin/apxs existe  (il vient du package httpd-devel)
# MP_TRACE=1 permet ensuite d'utiliser dans httpd.conf la directive PerlTrace
cd mod_perl-2.0.9
perl Makefile.PL MP_APXS=/usr/bin/apxs MP_TRACE=1
make
make test


# Si tout se passe bien on doit avoir une fin qui ressemble à
All tests successful.
Result: PASS


# Pour cette dernière commande il faut être root
su
make install

La commande suivante indique où sont les modules (mod_xxxxx.so) que Apache charge
/usr/bin/apxs -q LIBEXECDIR

C’est là que doit se trouver le nouveau module mod_perl.so qui est chargé dans la config du serveur web avec

LoadModule perl_module modules/mod_perl.so

Voir ce précédent ce post pour la configuration,

01 octobre 2014

mod_perl startup

Une fois que l'on a un couple {Apache2 + mod_perl2} adapté il faut faire une peu de configuration. Voici comment mettre en place mod_perl2  et verifier que tout marche.

Rappel: il faut au minimum mod_perl 2.0.9 pour Apache 2.4.x

1) Configurer Apache normalement pour qu'il affiche le fichier index.html de votre répertoire htdocs. Ceci est toujours utile de pouvoir servir des pages statiques sans faire appel à Perl.
NB: Inutile de configurer la partie cgi-bin, ou php ;-)


2) Quand l’étape #1 fonctionne ajouter cette simple ligne à la fin du fichier de configuration principale de apache (httpd.conf)

    Include conf/mod_perl2.conf

Ainsi on ne touchera plus au fichier de configuration principal, on travaillera sur mod_perl2.conf, dont voici le contenu de départ :

LoadModule perl_module modules/mod_perl.so

# la ligne suivante n'est utile que si on a installé le module
# Apache2::Request qui utilise APR::Request qui utilise libapreq2
#   yum install libapreq2
#   cpanm       APR::Request
#   cpanm       Apache2::Request
# (le but étant de ne plus utiliser CGI.pm)
LoadModule apreq_module modules/mod_apreq2.so

PerlPostConfigRequire /path/to/myCode/startup.pl
PerlOptions -SetupEnv
 

<Location /hello>
   SetHandler perl-script
   PerlResponseHandler Hello
   PerlOptions +ParseHeaders

</Location>

a) On charge le module mod_perl (c'est lui qui importe Perl dans Apache)
b) On désigne un script Perl à exécuter au démarrage de Perl (voir plus bas)
c) On désactive l'importation de l'environnement dans le contexte de chaque requête (plus sûr et plus rapide)
d) On annonce que l'url /hello sera traitée par le module Perl Hello.pm
Ce module gèrera lui-même les headers et il sera exécuté en tant que "perl-script" (bien que ce soit forcement un module)


3) Le module Hello.pm est très simple à écrire et à comprendre :

package Hello;
use strict;
use warnings;

sub handler {  # Le nom de la fonction est imposé
    print "Content-type: text/plain\n\n";
    print "Hello at : ". localtime . "\n";
    return Apache2::Const::OK;
}
1;


On le stocke dans /path/to/myCode/Hello.pm



4) Le script startup.pl ressemble à ceci

use lib qw(/path/to/myCode);   # voir "Attention #2" plus bas

use ModPerl::Util ();
use ModPerl::Registry ();
 
use Apache2::RequestRec ();
use Apache2::RequestIO ();
use Apache2::RequestUtil ();
use Apache2::ServerRec ();
use Apache2::ServerUtil ();
use Apache2::Connection ();
use Apache2::Log ();

use Apache2::Const -compile => ':common';

use APR::Table ();
use APR::Const -compile => ':common';

1;


Le plus important dans ce fichier est la première ligne car elle indique où seront vos modules Perl chargés de réponde aux requêtes. Les autres "use" préchargent des modules d'usage courant ce qui evitera de répéter ces "use" dans chaque module Perl.


Si vous devez ouvrir un accès à une base de donnée ce sera aussi dans ce script en utilisant Apache::DBI Exemple pour Postgresql

use Apache::DBI;
Apache::DBI->connect_on_init("dbi:Pg:dbname=myDB", 

  "myUSR", 
  "myPASS",
  {AutoCommit => 1, RaiseError => 1, PrintError => 1} 

);
Apache::DBI->setPingTimeOut("dbi:Pg:dbname=myDB", 30);


ATTENTION #1: Pour accéder à la base de donnée dans un module (handler) il faudra utiliser le classique $dbh = DBI->connect(...) Mais il faudra que tous les paramètres de connect() soit exactement les mêmes que ceux passé à connect_on_init();


ATTENTION #2: Dans le contexte de mod_perl2 "use FindBin;" ne marche pas comme espéré.
En effet $FindBin::Bin donne le point de démarrage du serveur Apache, pas celui de startup.pl.

A la place il faudra faire ce genre de gymnastique:

use File::Basename;
our $PERLBASE;
BEGIN {
  $PERLBASE = dirname( __FILE__ );
}
use lib $PERLBASE;



Dans tous les modules (handlers) vous pourrez accéder simplement à $::PERLBASE



01 août 2014

DBD-pg ActiveState & MSVC2013

Dernière étape de notre périple : compiler le driver DBI pour postgresql 9.3 sous Windows.

On suppose que sont déjà installés ces 3 logiciels :
-    Visual C/C++ (MSVC 2013)   (la version gratuite dite 'express' est suffisante)
-    Perl d’ActiveState 5.16           (vous devez pouvoir l’exécuter depuis la ligne de commande)
-    PostgreSQL 9.3.x                     (vous devez pouvoir vous y connecter en local)

(les versions sont données à titre indicatif. Il peut y avoir de variations)

1) Préparer le Makefile de DBD-pg

Télécharger ici : http://search.cpan.org/~turnstep/DBD-Pg/
puis décompacter les sources de DBD-pg 3.x

Ouvrir une ligne de commande (cmd.exe) à la racine des sources de DBD-pg
et taper ces 3 commandes:(à adapter suivant les versions de Postgres et de VC)
"C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat"
"C:\Program Files (x86)\PostgreSQL\9.3\pg_env.bat"
perl Makefile.PL
Si les environnements VC, Perl et PostgreSQL sont corrects tout se passe bien.

2) Compilation de DBD-pg

Taper la commande
nmake  
Si vous avez l’erreur  'C:\Program' is not recognized as an internal or external command, operable program or batch file. Voir dans l’article sur la compilation de mod_perl comment le corriger.

3) Tests de DBD-pg

Avant de lancer les tests il faut créer un rôle de connexion  ‘test’ et une base de donnée ‘test’ appartenant au rôle ‘test’
NB: Si vous utilisez Postgresql 9.0 ou + récent, il faut que ce rôle ai les droits de superviseur sur la base ‘test’.

Adaptez si nécessaire et taper ces 3 commandes :
Set DBI_DSN=dbi:Pg:dbname=test
Set DBI_USER=test
Set DBI_PASS=xxxx
Puis lancer les tests :
nmake test
* Si vous avez des caractères ou des texte bizarres  et/ou si vous avez des erreurs du type
Failed test 'Dollar quotes with invalid characters are not parsed as identifier
C’est parce que les messages d’erreurs de postgresql ne sont pas en Anglais !
Le test attend « syntax error » et il trouve « erreur de syntaxe », et ça lui va pas...

Pour passer les messages du serveur postgresql en anglais :
Éditer le fichier postgresql.conf (il est dans le répertoire data) et remplacer 
  lc_messages = 'French_France.1252'
par 
  lc_messages = 'en_EN.utf8'

Truc : Pour passer la console Windows en UTF8 taper la commande
chcp 65001


Pour que le changement dans postgresql.conf prenne effet arrêter/redémarrer le serveur postgresql depuis une console en admin :
sc stop postgresql-9.3
sc start postgresql-9.3

* Que faire si vous avez l’erreur suivante ?
    error: permission denied for relation pg_largeobject


Depuis PostgreSQL 9.0 il faut être superuser de la base pour accéder à pg_largeobject.
L’erreur est donc normale si le user ‘test’ n’est pas superuser ET si c'est au moins posgres 9. Vous pouvez lui donner ce droit, refaire les tests.

* Si tout se passe bien ça finit par
...
t/99cleanup.t ....... 1/1 Removing test database directory
t/99cleanup.t ....... ok
All tests successful.
Files=16, Tests=2089, 21 wallclock secs
Result: PASS

 

4) Installation de DBD-pg

Dernière commande:
nmake install
Il s’agit juste de copier des fichiers donc pas de problèmes attendus.


Partez pas !
Il reste à supprimer la base de donnée et le rôle utilisé pour les tests.