mon $self = shift in Perl; une explication

j'ai vraiment du mal à comprendre l'intersection de Oo Perl et my $self = shift; la documentation sur ces éléments individuels est excellente, mais aucun d'entre eux que j'ai trouvé touche à la façon dont ils travaillent ensemble.

J'ai utilisé Moose pour faire des modules avec des attributs, et bien sûr il est utile de référencer l'attribut d'un module dans ce module. On m'a dit encore et encore d'utiliser my $self = shift; dans un sous-programme pour assigner les attributs du module à cette variable. Ce fait sens et fonctionne, mais quand je passe aussi des arguments au sous-programme, ce processus prend clairement le premier élément du @ARGV array et l'attribue à $self.

Est-ce que quelqu'un peut m'expliquer comment je peux utiliser shift pour obtenir un accès interne aux attributs d'un module, tout en passant des arguments dans le @ARGV array?

25
demandé sur Alex H Hadik 2013-10-03 18:29:02

3 réponses

tout d'abord, un sous-programme ne passe pas le @ARGV array. Plutôt, tous les paramètres passés à un sous-programme sont aplatis dans une liste unique représentée par @_ à l'intérieur du sous-programme. Le tableau @ARGV est disponible au niveau supérieur de votre script, contenant les arguments en ligne de commande passés à votre script.

maintenant, en Perl, quand vous appelez une méthode sur un objet, l'objet est implicitement passé comme paramètre à la méthode.

Si vous ignorez l'héritage,

 $obj->doCoolStuff($a, $b);

est équivalent à

 doCoolStuff($obj, $a, $b);

ce qui signifie le contenu de @_ dans la méthode doCoolStuff serait: @_ = ($obj, $a, $b);

Maintenant,shift la fonction builtin, sans aucun paramètre, déplace un élément hors de la variable de tableau par défaut @_. Dans ce cas, ce serait $obj.

Donc quand vous faites $self = shift, vous êtes effectivement dire $self = $obj.

j'espère aussi que cela explique comment passer d'autres paramètres d'une méthode via le -> la notation. En continuant l'exemple que j'ai mentionné ci-dessus, ce serait comme:

sub doCoolStuff {
  # Remember @_ = ($obj, $a, $b)
  my $self = shift;
  my ($a, $b) = @_;

en Outre, alors que Moose est un grand calque d'objet pour Perl, il ne supprime pas l'exigence que vous devez initialiser le $self vous dans chaque méthode. Rappelez-vous toujours ceci. Tandis que des langages comme C++ et Java initialisent la référence d'objet this implicitement, en Perl, vous devez le faire explicitement pour chaque méthode que vous écrivez.

54
répondu Nikhil 2017-06-10 21:20:15

Dans le code, shift() est l'abréviation de shift(@ARGV). @ARGV contient les arguments en ligne de commande.

Dans un sous, shift() est l'abréviation de shift(@_). @_ contient les arguments du sous-marin.

my $self = shift; saisit le premier argument du sous-marin. Quand on appelle une méthode, l'invocant (ce qui reste du ->) est passée comme premier paramètre. En d'autres termes,

$o->method(@a)

est similaire à

my $sub = $o->can('method');
$sub->($o, @a);

Dans cet exemple, my $self = shift; assigner $o$self.

8
répondu ikegami 2013-10-03 14:43:52

Si vous appelez:

$myinstance->myMethod("my_parameter");  

est la même qu'en faisant:

myMethod($myinstance, "my_parameter");  

mais si tu fais:

myMethod("my_parameter");  

seul le "my_parameter" sera passé.

alors si à l'intérieur de myMethod vous faites toujours:

 $self = shift @_;  

$self sera la référence de l'objet lorsque myMethod id appelé à partir d'un contexte d'objet

mais sera "my_parameter" quand appelé d'une autre méthode à l'intérieur sur une manière procédurale.

Soyez conscient de cela;

2
répondu dg546gs4d65 2014-03-03 00:19:02