.\" Automatically generated by Pod::Man 2.09 (Pod::Simple 3.04) .\" .\" Standard preamble: .\" ======================================================================== .de Sh \" Subsection heading .br .if t .Sp .ne 5 .PP \fB\\$1\fR .PP .. .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. | will give a .\" real vertical bar. \*(C+ will give a nicer C++. Capital omega is used to .\" do unbreakable dashes and therefore won't be available. \*(C` and \*(C' .\" expand to `' in nroff, nothing in troff, for use with C<>. .tr \(*W-|\(bv\*(Tr .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' 'br\} .\" .\" If the F register is turned on, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . nr % 0 . rr F .\} .\" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .hy 0 .if n .na .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "PERLOBJ 1" .TH PERLOBJ 1 "2006-03-12" "DocFr" "User Contributed Perl Documentation" .SH "NAME/NOM" .IX Xref "objet POO" .IX Header "NAME/NOM" perlobj \- Objets en Perl .SH "DESCRIPTION" .IX Header "DESCRIPTION" Tout d'abord, vous devez comprendre ce que sont les re\*'fe\*'rences en Perl. Voir perlref pour cela. Ensuite, si le document qui suit vous semble encore trop complique\*', vous trouverez des tutoriels sur la programmation oriente\*'e objet en Perl dans perltoot et perltooc. .PP Si vous e\*^tes toujours avec nous, voici trois de\*'finitions tre\*`s simples que vous devriez trouver rassurantes. .IP "1." 4 Un objet est simplement une re\*'fe\*'rence qui sait a\*` quelle classe elle appartient. .IP "2." 4 Une classe est simplement un paquetage qui fournit des me\*'thodes pour manipuler les re\*'fe\*'rences d'objet. .IP "3." 4 Une me\*'thode est simplement un sous-programme qui attend une re\*'fe\*'rence d'objet (ou un nom de paquetage, pour les me\*'thodes de classe) comme premier argument. .PP Nous allons maintenant couvrir ces points plus en de\*'tails. .Sh "Un objet est simplement une re\*'fe\*'rence" .IX Xref "objet bless constructeur new" .IX Subsection "Un objet est simplement une re'fe'rence" Contrairement a\*`, disons, \*(C+, Perl ne fournit aucune syntaxe particulie\*`re pour les constructeurs. Un constructeur est juste un sous-programme qui retourne une re\*'fe\*'rence a\*` quelque chose qui a e\*'te\*' \*(L"consacre\*'\*(R" (ou \*(L"be\*'ni\*(R") par une classe, ge\*'ne\*'ralement la classe dans laquelle le sous-programme est de\*'fini. Voici un constructeur typique\ : .PP .Vb 2 \& package Critter; \& sub new { bless {} } .Ve .PP Le mot \f(CW\*(C`new\*(C'\fR n'a rien de spe\*'cial. Vous auriez aussi bien pu e\*'crire un constructeur de cette fac\*,on\ : .PP .Vb 2 \& package Critter; \& sub spawn { bless {} } .Ve .PP Ceci peut me\*^me e\*^tre pre\*'fe\*'rable car les programmeurs \*(C+ n'auront pas tendance a\*` penser que \f(CW\*(C`new\*(C'\fR fonctionne en Perl de la me\*^me manie\*`re qu'en \*(C+. Ce n'est pas le cas. Nous vous recommandons de nommer vos constructeurs de fac\*,on qu'ils aient un sens en fonction du contexte du proble\*`me que vous re\*'solvez. Par exemple, les constructeurs dans l'extension Tk de Perl portent les noms des widgets qu'ils cre\*'ent. .PP Une diffe\*'rence entre les constructeurs de Perl et de \*(C+ est qu'en Perl, ils doivent allouer leur propre me\*'moire (l'autre diffe\*'rence est qu'ils n'appellent pas automatiquement les constructeurs de classe de base surcharge\*'s). Le \f(CW\*(C`{}\*(C'\fR alloue un hachage anonyme ne contenant aucune paire cle\*'/valeur, et le retourne. Le \fIbless()\fR prend cette re\*'fe\*'rence, dit a\*` l'objet qu'il re\*'fe\*'rence qu'il est de\*'sormais un Critter et retourne la re\*'fe\*'rence. C'est pour que cela soit plus pratique, car l'objet re\*'fe\*'rence\*' sait lui\-me\*^me qu'il a e\*'te\*' consacre\*', et sa re\*'fe\*'rence aurait pu e\*^tre retourne\*'e directement, comme ceci\ : .PP .Vb 5 \& sub new { \& my $self = {}; \& bless $self; \& return $self; \& } .Ve .PP Vous voyez souvent de telles choses dans des constructeurs plus complique\*'s qui veulent utiliser des me\*'thodes de la classe pour la construction\ : .PP .Vb 6 \& sub new { \& my $self = {}; \& bless $self; \& $self\->initialize(); \& return $self; \& } .Ve .PP Si vous vous souciez de l'he\*'ritage (et vous devriez ; voir \&\*(L"Modules: cre\*'ation, utilisation et abus\*(R" in perlmodlib), alors vous pre\*'fe\*'rerez utiliser la forme a\*` deux arguments de bless pour que vos constructeurs puissent e\*^tre utilise\*'s par he\*'ritage\ : .PP .Vb 7 \& sub new { \& my $class = shift; \& my $self = {}; \& bless $self, $class; \& $self\->initialize(); \& return $self; \& } .Ve .PP Ou si vous vous attendez a\*` ce que les gens appellent non seulement \f(CW\*(C`CLASS\->new()\*(C'\fR, mais aussi \f(CW\*(C`$obj\->new()\*(C'\fR, alors utilisez quelque chose comme ce qui suit (notez que cet appel a\*` \fInew()\fR via une instance ne re\*'alise aucune copie automatiquement. Que vous vouliez une copie superficielle ou en profondeur, dans tous les cas vous aurez a\*` e\*'crire le code correspondant). La me\*'thode \fIinitialize()\fR sera celle de la classe dans laquelle nous consacrons l'objet\ : .PP .Vb 8 \& sub new { \& my $this = shift; \& my $class = ref($this) || $this; \& my $self = {}; \& bless $self, $class; \& $self\->initialize(); \& return $self; \& } .Ve .PP A\*` l'inte\*'rieur du paquetage de la classe, les me\*'thodes ge\*'reront habituellement la re\*'fe\*'rence comme une re\*'fe\*'rence ordinaire. A\*` l'exte\*'rieur du paquetage, la re\*'fe\*'rence est ge\*'ne\*'ralement traite\*'e comme une valeur opaque a\*` laquelle on ne peut acce\*'der qu'a\*` travers les me\*'thodes de la classe. .PP Bien qu'un constructeur puisse en the\*'orie re-consacrer un objet re\*'fe\*'rence\*' appartenant couramment a\*` une autre classe, ceci va presque certainement vous causer des proble\*`mes. La nouvelle classe est responsable de tout le nettoyage qui viendra plus tard. La pre\*'ce\*'dente conse\*'cration est oublie\*'e, puisqu'un objet ne peut appartenir qu'a\*` une seule classe a\*` la fois (me\*^me si bien su\*^r il est libre d'he\*'riter de me\*'thodes en provenance de nombreuses classes). Si toutefois vous vous retrouvez dans l'obligation de le faire, la classe parent a probablement un mauvais comportement. .PP Une clarification\ : les objets de Perl sont consacre\*'s. Les re\*'fe\*'rences ne le sont pas. Les objets savent a\*` quel paquetage ils appartiennent. Pas les re\*'fe\*'rences. La fonction \fIbless()\fR utilise la re\*'fe\*'rence pour trouver l'objet. Conside\*'rez l'exemple suivant\ : .PP .Vb 4 \& $a = {}; \& $b = $a; \& bless $a, BLAH; \& print "\e$b is a ", ref($b), "\en"; .Ve .PP Ceci rapporte \f(CW$b\fR comme e\*'tant un \s-1BLAH\s0, il est donc e\*'vident que \fIbless()\fR a agi sur l'objet et pas sur la re\*'fe\*'rence. .Sh "Une classe est simplement un paquetage" .IX Xref "classe paquetage package @ISA he\*'ritage" .IX Subsection "Une classe est simplement un paquetage" Contrairement a\*`, disons, \*(C+, Perl ne fournit aucune syntaxe spe\*'ciale pour les de\*'finitions de classes. Vous utilisez un paquetage en tant que classe en mettant des de\*'finitions de me\*'thodes dans la classe. .PP Il existe un tableau spe\*'cial appele\*' \f(CW@ISA\fR a\*` l'inte\*'rieur de chaque paquetage, qui dit ou\*` trouver une me\*'thode si on ne la trouve pas dans le paquetage courant. C'est de cette fac\*,on que Perl imple\*'mente l'he\*'ritage. Chaque e\*'le\*'ment du tableau \f(CW@ISA\fR est juste le nom d'un autre paquetage qui s'ave\*`re e\*^tre un paquetage de classe. Les classes sont fouille\*'es (en profondeur tout d'abord) a\*` la recherche des me\*'thodes manquantes dans l'ordre ou\*` elles apparaissent dans \&\f(CW@ISA\fR. Les classes accessibles a\*` travers \f(CW@ISA\fR sont les classes de base de la classe courante. .PP Toutes les classes he\*'ritent implicitement de la classe \f(CW\*(C`UNIVERSAL\*(C'\fR en tant que dernie\*`re classe de base. Plusieurs me\*'thodes couramment utilise\*'es sont automatiquement fournies par la classe \s-1UNIVERSAL\s0 ; voir \&\*(L"Me\*'thodes \s-1UNIVERSAL\s0 par de\*'faut\*(R" pour plus de de\*'tails. .IX Xref "UNIVERSAL classe de base base, classe de" .PP Si une me\*'thode manquante est trouve\*'e dans une classe de base, elle est mise en cache dans la classe courante pour plus d'efficacite\*'. Modifier \&\f(CW@ISA\fR ou de\*'finir de nouveaux sous-programmes invalide le cache et force Perl a\*` recommencer la recherche. .PP Si ni la classe courante, ni ses classes de base nomme\*'es, ni la classe \&\s-1UNIVERSAL\s0 ne contiennent la me\*'thode requise, ces trois endroits sont fouille\*'s de nouveau, cette fois a\*` la recherche d'une me\*'thode appele\*'e \s-1\fIAUTOLOAD\s0()\fR. Si une me\*'thode \s-1AUTOLOAD\s0 est trouve\*'e, cette me\*'thode est appele\*'e a\*` la place de la me\*'thode manquante et le nom complet de la me\*'thode qui devait e\*^tre appele\*'e est stocke\*' dans la variable globale de paquetage \f(CW$AUTOLOAD\fR. .IX Xref "AUTOLOAD" .PP Si rien de tout cela ne marche, Perl abandonne finalement et se plaint. .PP Si vous voulez stopper l'he\*'ritage par \s-1AUTOLOAD\s0 a\*` votre niveau, il vous suffit de dire\ : .IX Xref "AUTOLOAD" .PP .Vb 1 \& sub AUTOLOAD; .Ve .PP et l'appel mourra via die en utilisant le nom de la me\*'thode appele\*'e. .PP Les classes de Perl ne font que de l'he\*'ritage de me\*'thodes. L'he\*'ritage de donne\*'es est laisse\*' a\*` la charge de la classe elle\-me\*^me. Ce n'est pas, et de loin, un proble\*`me en Perl car la plupart des classes stockent les attributs de leurs objets dans un hachage anonyme qu'elles utilisent comme un espace de nommage qui leur est propre mais qui peut e\*^tre cisele\*' par les diverses autres classes qui veulent faire quelque chose de l'objet. Le seul proble\*`me dans ce cas est que vous ne pouvez pas e\*^tre certain que vous n'utilisez pas un morceau du hachage qui serait de\*'ja\*` utilise\*' par ailleurs. Une fac\*,on raisonnable de le contourner est de pre\*'fixer vos noms d'attributs par le nom de votre paquetage. .IX Xref "he\*'ritage, me\*'thode he\*'ritage, donne\*'e" .PP .Vb 4 \& sub bump { \& my $self = shift; \& $self\->{ _\|_PACKAGE_\|_ . ".count"}++; \& } .Ve .Sh "Une me\*'thode est simplement un sous-programme" .IX Xref "me\*'thode" .IX Subsection "Une me'thode est simplement un sous-programme" Contrairement a\*`, disons, \*(C+, Perl ne fournit aucune syntaxe spe\*'ciale pour la de\*'finition des me\*'thodes (il fournit toutefois un peu de syntaxe pour l'invocation des me\*'thodes. Vous en saurez plus a\*` ce sujet plus tard). Une me\*'thode s'attend a\*` ce que son premier argument soit l'objet (re\*'fe\*'rence) ou le paquetage (chai\*^ne) pour lequel elle est invoque\*'e. Il existe deux fac\*,ons d'appeler les me\*'thodes, que nous appellerons des me\*'thodes de classe et des me\*'thodes d'instance. .PP Une me\*'thode de classe attend un nom de classe comme premier argument. Elle fournit une fonctionnalite\*' a\*` la classe toute entie\*`re mais pas a\*` un objet en particulier appartenant a\*` cette classe. Les constructeurs sont souvent des me\*'thodes de classe mais voyez perltoot et perltooc pour des alternatives. De nombreuses me\*'thodes de classe ignorent tout simplement leur premier argument car elles savent de\*'ja\*` dans quel paquetage elles sont, et se moquent du paquetage via lequel elles ont e\*'te\*' invoque\*'es (ce ne sont pas ne\*'cessairement les me\*^mes, car les me\*'thodes de classe suivent l'arbre d'he\*'ritage tout comme les me\*'thodes d'instance ordinaires). Un autre usage typique des me\*'thodes de classe est la recherche d'un objet par son nom\ : .PP .Vb 4 \& sub find { \& my ($class, $name) = @_; \& $objtable{$name}; \& } .Ve .PP Une me\*'thode d'instanciation attend une re\*'fe\*'rence a\*` un objet comme premier argument. Typiquement, elle change le premier argument en variable \*(L"self\*(R" ou \*(L"this\*(R", puis l'utilise comme une re\*'fe\*'rence ordinaire. .PP .Vb 7 \& sub display { \& my $self = shift; \& my @keys = @_ ? @_ : sort keys %$self; \& foreach $key (@keys) { \& print "\et$key => $self\->{$key}\en"; \& } \& } .Ve .Sh "Invocation de me\*'thode" .IX Subsection "Invocation de me'thode" .IX Xref "invocation me\*'thode fle\*`che ->" .PP Pour des raisons historiques et autres, Perl offre deux moyens e\*'quivalent d'appeler des me\*'thodes. Le plus simple et le plus courant est la notation a\*` base de fle\*`che\ : .PP .Vb 2 \& my $fred = Critter\->find("Fred"); \& $fred\->display("Height", "Weight"); .Ve .PP L'usage de la fle\*`che avec des re\*'fe\*'rences doit de\*'ja\*` vous e\*^tre familier. En fait, comme \f(CW$fred\fR fait re\*'fe\*'rence a\*` un objet, vous pouvez conside\*'rer l'appel a\*` la me\*'thode comme une autre forme de de\*'re\*'fe\*'rencement. .PP Quoiqu'il y ait a\*` gauche de la fle\*`che, que ce soit une re\*'fe\*'rence ou un nom de classe, c'est ce qui sera passe\*' a\*` la me\*'thode comme premier argument. Donc le code ci-dessus est quasiment e\*'quivalent a\*`\ : .PP .Vb 2 \& my $fred = Critter::find("Critter", "Fred"); \& Critter::display($fred, "Height", "Weight"); .Ve .PP Comment Perl peut-il savoir dans quel paquetage est la me\*'thode ? En regardant la partie gauche de la fle\*`che, qui doit e\*^tre soit une re\*'fe\*'rence a\*` un objet soit un nom de classe, c'est\-a\*`\-dire quelque chose qui a e\*'te\*' consacre\*' par un paquetage. C'est a\*` partir de ce paquetage que Perl commence la recherche. Si ce paquetage ne propose pas cette me\*'thode, Perl cherche dans les classes de base de ce paquetage et ainsi de suite. .PP Si besoin est, vous \fIpouvez\fR forcer Perl a\*` commencer sa recherche dans un autre paquetage. .PP .Vb 2 \& my $barney = MyCritter\->Critter::find("Barney"); \& $barney\->Critter::display("Height", "Weight"); .Ve .PP Dans cet exemple \f(CW\*(C`MyCritter\*(C'\fR est a priori une sous-classe de \f(CW\*(C`Critter\*(C'\fR qui de\*'finit ses propres version de \fIfind()\fR et de \fIdisplay()\fR. Nous ne les avons pas spe\*'cifier mais cela n'a pas d'importance puisqu'ici nous forc\*,ons Perl a\*` commencer sa recherche de subroutines dans \f(CW\*(C`Critter\*(C'\fR. .PP Un cas spe\*'cial de la situation pre\*'ce\*'dente est l'utilisation de la pseudo classe \f(CW\*(C`SUPER\*(C'\fR pour demander a\*` Perl d'effectuer la recherche de me\*'thodes dans les paquetages de la liste \f(CW@ISA\fR de la classe courante. .IX Xref "SUPER" .PP .Vb 2 \& package MyCritter; \& use base 'Critter'; # sets @MyCritter::ISA = ('Critter'); \& \& sub display { \& my ($self, @args) = @_; \& $self\->SUPER::display("Name", @args); \& } .Ve .PP Il est important de noter que \f(CW\*(C`SUPER\*(C'\fR se re\*'fe\*`rent a\*` la (aux) superclasse(s) du \fIpaquetage courant\fR et non a\*` la (aux) superclasse(s) de l'objet lui\-me\*^me. De plus, la pseudo classe \f(CW\*(C`SUPER\*(C'\fR peut e\*^tre utilise\*'e comme modificateur d'un nom de me\*'thode mais pas aux autres endroits ou\*` un nom de classe est utilise\*'. Exemple\ : .IX Xref "SUPER" .PP .Vb 3 \& something\->SUPER::method(...); # OK \& SUPER::method(...); # MAUVAIS \& SUPER\->method(...); # MAUVAIS .Ve .PP A\*` la place d'un nom de classe ou d'une re\*'fe\*'rence a\*` un objet, vous pouvez utiliser n'importe quelle expression qui retourne quelque chose pouvant apparai\*^tre a\*` gauche de la fle\*`che. Donc, l'instruction suivante est valide\ : .PP .Vb 1 \& Critter\->find("Fred")\->display("Height", "Weight"); .Ve .PP et celle-ci aussi\ : .PP .Vb 1 \& my $fred = (reverse "rettirC")\->find(reverse "derF"); .Ve .PP A\*` droite de la fle\*`che, on trouve habituellement le nom de la me\*'thode mais une simple variable scalaire contenant soit le nom de la me\*'thode soit une re\*'fe\*'rence a\*` un sous-programme peut tre\*`s bien convenir. .Sh "Syntaxe objet indirecte" .IX Xref "syntaxe objet indirecte invocation, indirecte indirecte" .IX Subsection "Syntaxe objet indirecte" Une autre manie\*`re d'appeler une me\*'thode passe par la notation indirecte. Cette syntaxe e\*'tait utilise\*'e dans Perl 4 bien avant l'introduction des objets et sert encore avec les handle de fichiers comme dans\ : .PP .Vb 1 \& print STDERR "help!!!\en"; .Ve .PP Cette me\*^me syntaxe peut e\*^tre utilise\*'e pour appeler des me\*'thodes de classe ou d'instance. .PP .Vb 2 \& my $fred = find Critter "Fred"; \& display $fred "Height", "Weight"; .Ve .PP Notez bien l'absence de virgule entre l'objet ou le nom de classe et les parame\*`tres. C'est cela qui indique Perl que vous voulez faire appel a\*` une me\*'thode pluto\*^t qu'un classique appel de subroutine. .PP Mais que se passe-t-il s'il n'y a pas de parame\*`tres\ ? Dans ce cas Perl doit deviner ce que vous voulez faire. De plus, il doit le savoir \fIlors de la compilation\fR. Dans la plupart des cas, Perl devine correctement mais s'il se trompe, vous vous retrouvez avec un appel de me\*'thode a\*` la place d'un appel de fonction ou vice\-versa. Cela introduit de bogues subtils qu'il est difficile de de\*'tecter. .PP Par exemple, l'appel a\*` la me\*'thode \f(CW\*(C`new\*(C'\fR en notation indirecte \*(-- comme les programmeurs \*(C+ ont l'habitude de le faire \*(-- peut e\*^tre compile\*' de manie\*`re errone\*'e en un appel de subroutine s'il existe une fonction \f(CW\*(C`new\*(C'\fR dans la porte\*'e de l'appel. Cela se termine par l'appel de la subroutine \f(CW\*(C`new\*(C'\fR du paquetage courant pluto\*^t que par la me\*'thode de la classe voulue. Le compilateur tente de tricher en se souvenant des noms employe\*'s par des \f(CW\*(C`require\*(C'\fR mais le petit gain attendu ne vaut pas les anne\*'es de de\*'bogue ne\*'cessaires lorsqu'il se trompe. .PP Il y a un autre proble\*`me avec cette syntaxe\ : l'objet indirect est limite\*' a\*` un nom, une variable scalaire ou un bloc, pour e\*'viter de regarder trop loin en avant. (Ces me\*^mes re\*`gles bizarres sont utilise\*'es pour l'emplacement du handle de fichier dans les fonctions telles que \f(CW\*(C`print\*(C'\fR et \f(CW\*(C`printf\*(C'\fR) Ceci peut mener a\*` des proble\*`mes de pre\*'ce\*'dence horriblement troublants, comme dans ces deux lignes\ : .PP .Vb 2 \& move $obj\->{FIELD}; # probablement mauvaise ! \& move $ary[$i]; # probablement mauvaise ! .Ve .PP qui, e\*'tonnamment, sont interpre\*'te\*'es comme ceci\ : .PP .Vb 2 \& $obj\->move\->{FIELD}; # E\*'tonnant... \& $ary\->move([$i]); # Vous ne vous y attendiez pas ! .Ve .PP pluto\*^t que comme cela\ : .PP .Vb 2 \& $obj\->{FIELD}\->move(); # Vous seriez chanceux \& $ary[$i]\->move; # ... .Ve .PP Pour obtenir le comportement correct avec la notation indirect, vous pourriez utiliser un bloc autour de l'objet indirect\ : .PP .Vb 2 \& move {$obj\->{FIELD}}; \& move {$ary[$i]}; .Ve .PP He\*'las, vous aurez encore une ambigui\*:te\*' s'il existe une fonction nomme\*'e \f(CW\*(C`move\*(C'\fR dans le paquetage courant. \fBLa notation \f(CB\*(C`\->\*(C'\fB suffit pour lever toutes ces ambigui\*:te\*'s. Nous vous recommandons donc de l'utiliser en toutes circonstances.\fR En revanche, il peut encore arriver que vous ayez a\*` lire du code utilisant la notation indirecte. Il est donc important que vous soyez familiariser avec elle. .Sh "Me\*'thodes \s-1UNIVERSAL\s0 par de\*'faut" .IX Subsection "Me'thodes UNIVERSAL par de'faut" .IX Xref "UNIVERSAL" .PP Le paquetage \f(CW\*(C`UNIVERSAL\*(C'\fR contient automatiquement les me\*'thodes suivantes qui sont he\*'rite\*'es par toutes les autres classes\ : .IP "isa(\s-1CLASSE\s0)" 4 .IX Xref "isa" .IX Item "isa(CLASSE)" \&\f(CW\*(C`isa\*(C'\fR retourne \fIvrai\fR si son objet est consacre\*' par une sous-classe de \&\f(CW\*(C`CLASSE\*(C'\fR. .Sp Vous pouvez aussi appeler \f(CW\*(C`UNIVERSAL::isa\*(C'\fR comme une simple fonction avec deux arguments. Bien su\*^r, cela ne fonctionnera pas si quelqu'un rede\*'finit \f(CW\*(C`isa\*(C'\fR dans une classe, ce qui n'est donc pas une chose a\*` faire. .Sp Pour ve\*'rifier que ce que vous recevez est correct, utilisez la fonction \f(CW\*(C`blessed\*(C'\fR du module Scalar::Util : .Sp .Vb 3 \& if(blessed($ref) && $ref\->isa('Une::Classe')) { \& #... \& } .Ve .Sp \&\f(CW\*(C`blessed\*(C'\fR retourne le nom du paquetage ayant consacre\*' son argument (ou \f(CW\*(C`undef\*(C'\fR). .IP "can(\s-1METHODE\s0)" 4 .IX Xref "can" .IX Item "can(METHODE)" \&\f(CW\*(C`can\*(C'\fR ve\*'rifie si son objet posse\*`de une me\*'thode appele\*'e \f(CW\*(C`METHODE\*(C'\fR, si c'est le cas, une re\*'fe\*'rence a\*` la routine est retourne\*'e, sinon c'est \&\fIundef\fR qui est renvoye\*'. .Sp \&\f(CW\*(C`UNIVERSAL::can\*(C'\fR peut aussi e\*^tre appele\*' comme une subroutine a\*` deux arguments. Elle retourne toujours \fIundef\fR si son premier argument n'est pas un objet ou le nom d'une classe. Les me\*^mes conditions d'appel que celles de \f(CW\*(C`UNIVERSAL::isa\*(C'\fR s'appliquent. .IP "\s-1VERSION\s0( [\s-1NEED\s0] )" 4 .IX Xref "VERSION" .IX Item "VERSION( [NEED] )" \&\f(CW\*(C`VERSION\*(C'\fR retourne le nume\*'ro de version de la classe (du paquetage). Si l'argument \s-1NEED\s0 est fourni, elle ve\*'rifie que le nume\*'ro de version courant (tel que de\*'fini par la variable \f(CW$VERSION\fR dans le paquetage donne\*') n'est pas infe\*'rieur a\*` \s-1NEED\s0\ ; il mourra si ce n'est pas le cas. Cette me\*'thode est normalement appele\*'e en tant que me\*'thode de classe. Elle est appele\*'e automatiquement par la forme \f(CW\*(C`VERSION\*(C'\fR de \&\f(CW\*(C`use\*(C'\fR. .Sp .Vb 3 \& use A 1.2 qw(des routines importees); \& # qui implique : \& A\->VERSION(1.2); .Ve .PP \&\fB\s-1NOTE\s0\ :\fR \f(CW\*(C`can\*(C'\fR utilise directement le code interne de Perl pour la recherche de me\*'thode, et \f(CW\*(C`isa\*(C'\fR utilise une me\*'thode tre\*`s similaire et une strate\*'gie de cache. Ceci peut produire des effets e\*'tranges si le code Perl change dynamiquement \f(CW@ISA\fR dans un paquetage. .PP Vous pouvez ajouter d'autres me\*'thodes a\*` la classe \s-1UNIVERSAL\s0 via du code Perl ou \s-1XS\s0. Vous n'avez pas besoin de pre\*'ciser \f(CW\*(C`use UNIVERSAL\*(C'\fR (et vous ne devriez pas le faire) pour que ces me\*'thodes soient disponibles dans votre programme. .Sh "Destructeurs" .IX Xref "destructeur DESTROY" .IX Subsection "Destructeurs" Lorsque la dernie\*`re re\*'fe\*'rence a\*` un objet disparai\*^t, l'objet est automatiquement de\*'truit (Ce qui peut me\*^me se produire apre\*`s un \fIexit()\fR si vous avez stocke\*' des re\*'fe\*'rences dans des variables globales). Si vous voulez prendre le contro\*^le juste avant que l'objet ne soit libe\*'re\*', vous pouvez de\*'finir une me\*'thode \s-1DESTROY\s0 dans votre classe. Elle sera appele\*'e automatiquement au moment approprie\*', et vous pourrez y re\*'aliser tous les nettoyages supple\*'mentaires dont vous avez besoin. Perl passe une re\*'fe\*'rence a\*` l'objet qui va e\*^tre de\*'truit comme premier (et unique) argument. Souvenez-vous que cette re\*'fe\*'rence est une valeur en lecture seule, qui ne peut pas e\*^tre modifie\*'e en manipulant \f(CW$_[0]\fR au sein du destructeur. L'objet en lui\-me\*^me (i.e. le bidule vers lequel pointe la re\*'fe\*'rence, appele\*' \f(CW\*(C`${$_[0]}\*(C'\fR, \&\f(CW\*(C`@{$_[0]}\*(C'\fR, \f(CW\*(C`%{$_[0]}\*(C'\fR etc.) n'est pas soumis a\*` la me\*^me contrainte. .PP Puisque les me\*'thodes \s-1DESTROY\s0 peuvent e\*^tre appele\*'es n'importe quand, il est important de rendre locale toute variable globale utilise\*'e. En particulier, localisez \f(CW$@\fR su vous utiliser \f(CW\*(C`eval {}\*(C'\fR et localisez \&\f(CW$?\fR si vous utiliser \f(CW\*(C`system\*(C'\fR ou les apostrophes inverses. .PP Si vous vous arrangez pour re-consacrer la re\*'fe\*'rence avant la fin du destructeur, Perl appellera de nouveau la me\*'thode \s-1DESTROY\s0 apre\*`s la fin de l'appel en cours pour l'objet re\-consacre\*'. Cela peut e\*^tre utilise\*' pour une de\*'le\*'gation propre de la destruction d'objet, ou pour s'assurer que les destructeurs dans la classe de base de votre choix sont appele\*'s. L'appel explicite de \s-1DESTROY\s0 est aussi possible, mais n'est habituellement pas ne\*'cessaire. .PP Ne confondez pas ce qui pre\*'ce\*`de avec la fac\*,on dont sont de\*'truits les objets \fI\s-1CONTENUS\s0\fR dans l'objet courant. De tels objets seront libe\*'re\*'s et de\*'truits automatiquement en me\*^me temps que l'objet courant, pourvu qu'il n'existe pas ailleurs d'autres re\*'fe\*'rences pointant vers eux. .Sh "Re\*'sume\*'" .IX Subsection "Re'sume'" C'est a\*` peu pre\*`s tout sur le sujet. Il ne vous reste plus qu'a\*` aller acheter un livre sur la me\*'thodologie de conception oriente\*'e objet, et vous le frapper sur le front pendant les six prochains mois environ. .Sh "Ramasse-miettes a\*` deux phases" .IX Xref "ramasse-miettes garbage collector GC re\*'fe\*'rence circulaire circulaire, re\*'fe\*'rence DESTROY destructeur" .IX Subsection "Ramasse-miettes a` deux phases" Dans la plupart des cas, Perl utilise un syste\*`me de ramasse-miettes simple et rapide base\*' sur les re\*'fe\*'rences. Cela signifie qu'il se produit un de\*'re\*'fe\*'rencement supple\*'mentaire a\*` un certain niveau, donc si vous n'avez pas compile\*' votre exe\*'cutable de Perl en utilisant l'option \&\f(CW\*(C`\-O\*(C'\fR de votre compilateur C, les performances s'en ressentiront. Si vous \fIavez\fR compile\*' Perl avec \f(CW\*(C`cc \-O\*(C'\fR, cela ne comptera probablement pas. .PP Un souci plus se\*'rieux est que la me\*'moire inaccessible avec un compteur de re\*'fe\*'rences diffe\*'rent de ze\*'ro ne sera normalement pas libe\*'re\*'e. Par conse\*'quent, ceci est une mauvaise ide\*'e\ : .PP .Vb 4 \& { \& my $a; \& $a = \e$a; \& } .Ve .PP Alors me\*^me que la variable \f(CW$a\fR \fIdevrait\fR disparai\*^tre, elle ne le peut pas. Lorsque vous construirez des structures de donne\*'es re\*'cursives, vous devrez briser vous\-me\*^me explicitement l'auto\-re\*'fe\*'rence si vous ne voulez pas de fuite de me\*'moire. Par exemple, voici un noeud auto\-re\*'fe\*'rent comme ceux qu'on pourrait utiliser dans une structure d'arbre sophistique\*'e\ : .PP .Vb 8 \& sub new_node { \& my $self = shift; \& my $class = ref($self) || $self; \& my $node = {}; \& $node\->{LEFT} = $node\->{RIGHT} = $node; \& $node\->{DATA} = [ @_ ]; \& return bless $node => $class; \& } .Ve .PP Si vous cre\*'ez de tels noeuds, ils ne disparai\*^tront pas (actuellement) a\*` moins que vous ne brisiez leur auto\-re\*'fe\*'rence vous\-me\*^me (en d'autres termes, cela ne doit pas e\*^tre conside\*'re\*' comme une caracte\*'ristique et vous ne devriez pas compter la\*`\-dessus). .PP Ou presque. .PP Lorsqu'un thread de l'interpre\*'teur se termine finalement (habituellement au moment ou\*` votre programme se termine), une libe\*'ration de la me\*'moire pluto\*^t cou\*^teuse, mais comple\*`te par marquage et nettoyage est effectue\*'e, tout ce qui a e\*'te\*' alloue\*' par ce thread est de\*'truit. C'est essentiel pour pouvoir supporter Perl comme un langage embarque\*' et multithread. Par exemple, ce programme montre le ramassage des miettes en deux phases de Perl\ : .PP .Vb 2 \& #!/usr/bin/perl \& package Subtle; \& \& sub new { \& my $test; \& $test = \e$test; \& warn "CREATING " . \e$test; \& return bless \e$test; \& } \& \& sub DESTROY { \& my $self = shift; \& warn "DESTROYING $self"; \& } \& \& package main; \& \& warn "starting program"; \& { \& my $a = Subtle\->new; \& my $b = Subtle\->new; \& $$a = 0; # break selfref \& warn "leaving block"; \& } \& \& warn "just exited block"; \& warn "time to die..."; \& exit; .Ve .PP Exe\*'cute\*' en tant que \fI/tmp/test\fR, la sortie suivante est produite\ : .PP .Vb 8 \& starting program at /tmp/test line 18. \& CREATING SCALAR(0x8e5b8) at /tmp/test line 7. \& CREATING SCALAR(0x8e57c) at /tmp/test line 7. \& leaving block at /tmp/test line 23. \& DESTROYING Subtle=SCALAR(0x8e5b8) at /tmp/test line 13. \& just exited block at /tmp/test line 26. \& time to die... at /tmp/test line 27. \& DESTROYING Subtle=SCALAR(0x8e57c) during global destruction. .Ve .PP Avez-vous remarque\*' le \*(L"global destruction\*(R"\ ? C'est le ramasse-miettes du thread en train d'atteindre l'inaccessible. .PP Les objets sont toujours de\*'truits, me\*^me lorsque les re\*'fe\*'rences normales ne le sont pas. Les objets sont supprime\*'s lors d'une passe distincte avant les re\*'fe\*'rences ordinaires juste pour e\*'viter aux destructeurs d'objets d'utiliser des re\*'fe\*'rences ayant de\*'ja\*` e\*'te\*' elles\-me\*^mes de\*'truites. Les simples re\*'fe\*'rences ne sont supprime\*'es que si le niveau de destruction est supe\*'rieur a\*` 0. Vous pouvez tester les plus hauts niveaux de destruction globale en fixant la variable d'environnement \s-1PERL_DESTRUCT_LEVEL\s0, si \f(CW\*(C`\-DDEBUGGING\*(C'\fR a e\*'te\*' utilise\*'e lors de la compilation de perl. Voir \*(L"\s-1PERL_DESTRUCT_LEVEL\s0\*(R" in perlhack pour plus d'information. .PP Une strate\*'gie plus comple\*`te de ramassage des miettes sera imple\*'mente\*'e un jour. .PP En attendant, la meilleure solution est de cre\*'er une classe de conteneur non\-re\*'cursif de\*'tenant un pointeur vers la structure de donne\*'es auto\-re\*'fe\*'rentielle. Puis, de de\*'finir une me\*'thode \s-1DESTROY\s0 pour la classe de conteneurs qui brise manuellement les circularite\*'s dans la structure auto\-re\*'fe\*'rentielle. .SH "VOIR AUSSI" .IX Header "VOIR AUSSI" Des tutoriels plus doux et plus gentils sur la programmation oriente\*'e objet en Perl se trouvent dans perltoot, perlboot et perltooc. Vous devriez aussi jeter un oeil sur perlbot pour d'autres petits trucs concernant les objets, les pie\*`ges et les astuces, ainsi que sur perlmodlib pour des guides de style sur la construction de modules et de classes. .SH "TRADUCTION" .IX Header "TRADUCTION" .Sh "Version" .IX Subsection "Version" Cette traduction franc\*,aise correspond a\*` la version anglaise distribue\*'e avec perl 5.8.8. Pour en savoir plus concernant ces traductions, consultez . .Sh "Traducteur" .IX Subsection "Traducteur" Roland Trique <\fIroland.trique@free.fr\fR>. Mise a\*` jour : Paul Gaborit (Paul.Gaborit @ enstimac.fr). .Sh "Relecture" .IX Subsection "Relecture" Philippe de Visme <\fIphilippe@devisme.com\fR>