2009-11-16 4 views
1

Je crée un nouvel objet comme celui-ci:Quelle est la syntaxe appropriée pour stocker un tableau dans un hachage Perl?

TestObject->new(@array1, @array2) 

Ma méthode new ressemble à ceci:

sub new { 
    my $class = shift; 
    my $self = {}; 

    my $self->{Array1} = shift; 
    my $self->{Array2} = shift; 

    bless($self, $class); 

    return $self; 
} 

En tant que test simple pour accéder aux données, j'essaie cela, puis une fois que je le faire fonctionner, je peux construire une logique plus significative:

sub mymethod { 
    my $self = shift; 
    my $param = shift; 

    my $array1Value = shift(my $self->{Array1}); 
    my $array2Value = shift(my $self->{Array2}); 

    print $array1Value." ".$array2Value; 
} 

Mais quand je l'appelle mymethod, je reçois cette erreur:

Type of arg 1 to shift must be array (not hash element) at Tests/MyObject.pm line 21, near "})" 

Suggestions? J'ai lu this page on Perl data structures, mais ils n'ont pas d'exemples pour créer un hachage de tableaux en utilisant les arguments d'une méthode utilisant shift. Donc, mon problème pourrait être là.

+1

Qu'est-ce que c'est exactement? 'shift (mon $ self -> {Array1})' – innaM

Répondre

0

vous devez derefernece ref tableau:

@{$self->{Array2}} 

Par ailleurs, si vous utilisez OO Je suggère avec insistance que vous regardez dans Moose. Cela rendra votre vie beaucoup plus facile!

+6

Je pense que vous auriez aussi besoin de le référencer en premier lieu, n'est-ce pas? Comme '-> new (\ @ array1, \ @ array2)'? – Kev

+0

Cela a fonctionné. Quand j'ai essayé ça, j'ai juste essayé @ $ self -> {Array2}, en oubliant les {et} around $ self -> {Array2}. –

+2

Cette réponse ignore complètement le problème de la transmission de tableaux réels dans une fonction, ce qui signifie que le code peut être compilé mais DTWT. – darch

5

Lorsque vous transmettez des tableaux en tant que paramètres, ils sont aplatis. Vous pouvez passer des références à eux. Voir perlsub

#!/usr/bin/env perl 

package foo; 

sub new { 
    my $class = shift; 
    my $self = {}; 

    $self->{Array1} = shift; 
    $self->{Array2} = shift; 

    bless($self, $class); 

    return $self; 
} 

sub mymethod { 
    my $self = shift; 
    my $param = shift; 

    my $array1Value = shift(@{$self->{Array1}}); 
    my $array2Value = shift(@{$self->{Array2}}); 

    print "$array1Value $array2Value\n"; 
} 

package main; 

my @a = (0, 1, 2); 
my @b = (3, 4, 5); 
my $o = new foo(\@a, \@b);; 
$o->mymethod; 
+3

Minor nit: Ne pas utiliser la syntaxe indirecte d'objet dans Perl (new Foo par opposition au meilleur Foo-> new). Cf. http://perldoc.perl.org/perlobj.html#Indirect-Object-Syntax – tsee

+0

Voir aussi http://stackoverflow.com/questions/429657/what-is-the-difference-between-new-someclass-and- someclass-new-in-perl – Ether

+1

N'utilisez pas non plus tous les noms de paquets en minuscules. –

4

vous devez utiliser des pointeurs vers des tableaux, pas de tableaux dans ce cas:

TestObject->new([@array1], [@array2]) 

puis plus tard

my $array1Value = shift(@{$self->{Array1}}); 
+3

new (\ @ array1, \ @ array2) sera beaucoup plus efficace puisque [@foo] crée un nouveau tableau anonyme et ensuite (superficiellement) copie les éléments de @foo dedans alors que \ @foo crée une référence au tableau existant . Notez également qu'en Perl, nous nous référons généralement à ceci comme une référence, pas comme un pointeur. Il n'y a pas de pointeurs de type C dans Perl. – tsee

+1

c'est exactement parce que j'utilise généralement la syntaxe [] au lieu de \ @.L'objet est censé encapsuler des données; il ne peut être responsable de tout ce qui arrive à ces réseaux en dehors de son contexte. La question de l'efficacité IMO ne sera soulevée que dans de rares cas où nous devons gérer d'énormes volumes de données et affiner les données en copiant – catwalk

+1

catwalk: alors vous voudrez peut-être une copie en profondeur (par exemple Storable :: dclone); '[@foo]' va copier les valeurs dans @foo, mais le nouveau tableau sera toujours connecté aux valeurs accessibles depuis l'ancien si les valeurs sont elles-mêmes des références. – ysth

1

Vous décalant un arrayref au lieu d'un véritable tableau.

La syntaxe ytou're probablement à la recherche est:

my $array1Value = shift @{ $self->{Array1} }; 
my $array2Value = shift @{ $self->{Array2} }; 

Notez comment le tableau est déréférencé en utilisant @.

+3

Méfiez-vous également que cela va modifier le tableau d'origine, pas une copie de celui-ci. – Kev

+0

Je suppose que c'est ce qu'il veut, car il utilise 'shift 'au lieu de l'indice, mais cela vaut la peine d'être mentionné. +1 –

+0

C'est en effet ce que je veux. –

Questions connexes