2010-11-02 4 views
2

je suis en train de créer un module qui est comme ceComment garder une variable portée à tous les sous-routines

package MyModule; 

use strict; 
use Exporter; 
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS); 

$VERSION = 1.00; 
@ISA = qw(Exporter); 
@EXPORT = qw(func1); 

sub func1 {  
    my x = shift;  
    print x;  
    func2();  
} 

sub func2 {  
    print x;  
} 

et à partir d'un script perl, je fais appel func1 du module et le passage d'une variable x. comment puis-je rendre cette variable visible aux deux sous-programmes ou dire toutes les fonctions à l'intérieur de ce module. S'il vous plaît aider.

Répondre

4

Déclare $x dans le cadre du fichier en utilisant my ou our:

my $x; 

# subroutines definition 

fichier a Plus grande portée lexicale, de sorte que la variable sera visible pour le reste du code (sauf si vous le re-déclarer dans une portée interne en utilisant my).

+0

Merci, cela a fonctionné – alp

+0

'our' est une chose un peu drôle, dans la mesure où il est en fait un alias lexical à une variable globale. – tchrist

3

Faire $x lexical dans le fichier package plutôt qu'un seul sous-programme:

package MyModule; 

use strict; 
use Exporter; 
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS); 

$VERSION = 1.00; 
@ISA = qw(Exporter); 
@EXPORT = qw(func1); 

my $x; 

sub func1 { 

    $x = shift; 
    print $x; 

    func2(); 
} 

sub func2 { 

    print $x; 
} 

Mais cet exemple ne fait pas vraiment de sens. Un exemple plus raisonnable serait de définir un descripteur de fichier lexical qui sous-routines multiples dans le package imprimer à:

package PoorManLogger; 

my $fileHandle; 

sub initialize { open $fileHandle, '<', +shift } 

sub alert { print $fileHandle 'ALERT: ', @_, "\n"; } 

sub debug { print $fileHandle 'DEBUG: ', @_, "\n"; } 

sub close { close $fileHandle; } # Though this isn't technically needed. 

1; 
+0

Merci, cela a fonctionné . – alp

+2

Les lexiques ont une portée de fichier et de bloc. Ils ne sont pas liés aux paquets. –

+0

Il est plus correct de dire que ** lexicals a une portée ** - qui est un concept sans rapport avec les paquets - et qu'une portée est un fichier, un bloc ou une chaîne 'eval'. Une autre façon d'y penser est d'assimiler les étendues et les blocs, mais ensuite vous devez mettre des boucles imaginaires autour des fichiers et des chaînes 'eval'. – tchrist

-1

voir our

(commentaires à ma suggestion sont correctes, ma suggestion n'a pas été)

+1

Cela crée une variable qui est visible en dehors de la portée du fichier en cours, ce qui est plus que ce que l'OP a demandé. – Ether

+1

On pourrait ergoter sur le fait que 'our' crée réellement * une variable, plutôt que d'accorder simplement une vue dans le paquet. Mais je crains que cela ne se transforme en une sorte d'enquête ontologique profonde. ☹ – tchrist

2

L'un des principaux avantages de OO est l'encapsulation:

#!/usr/bin/perl 

package MyModule; 

use strict; use warnings; 

sub new { 
    my $class = shift; 
    bless { x => shift } => $class; 
} 

sub x { 
    my $self = shift; 
    $self->{x} = shift if @_; 
    return $self->{x}; 
} 

sub func2 { 
    my $self = shift; 
    print $self->x, "\n"; 
} 

package main; 

use strict; use warnings; 

my $m = MyModule->new(5); 

$m->func2; 

$m->x(7); 

$m->func2; 
+0

J'adore comment le même sub est un getter _and_ setter ... – Zaid

+0

ne serait pas 'if (@_) {' fonctionner mieux que le test 'defined', attrapant le cas de légitimement assigner' undef' à 'x ' –

+0

@Eric Bien sûr. Cela fait longtemps que je n'ai pas écrit d'accesseurs. –