2015-10-12 13 views
6

Desidero sovrascrivere new in modo che la mia classe possa essere creata solo passando un argomento al costruttore, né più né meno.Un costruttore con solo 1 argomento in Perl 6

class MyClass { 
    has $.var1; 

    method new($var1) { 
    return MyClass.new(var1 => $var1); 
    } 
} 

my $my_class1 = MyClass.new(33); 
say $my_class1.var1; 

L'errore è:

Too few positionals passed; expected 2 arguments but got 1 
    in method new at test1.pl6:28 
    in method new at test1.pl6:28 
    in block <unit> at test1.pl6:33 

Che succede con esso?

risposta

10

costruttori personalizzati bisogno di chiamare bless, cioè

class MyClass { 
    has $.var1; 

    method new($var1) { 
     return self.bless(var1 => $var1); 
    } 
} 

Ci sono alcune cose che possono essere migliorate, ad esempio

  • uno potrebbe aggiungere un parametro esplicito invocant e utilizzare :U per fare .new() fallire se richiamato sugli oggetti di istanza
  • l'esplicito return è superfluo - l'ultima espressione all'interno del metodo verrà comunque restituita e Al momento, fa male in realtà prestazioni
  • c'è zucchero sintattico per il passaggio di un argomento di nome tenuto in una variabile con lo stesso nome

Mettere tutto insieme, si finisce con

class MyClass { 
    has $.var1; 

    method new(MyClass:U: $var1) { 
     self.bless(:$var1); 
    } 
} 

Quanto a dove il tuo errore proviene da:

Il tuo metodo new è dichiarato di prendere un argomento posizionale (dando un conteggio totale di 2 argomenti previsti a causa del richiamo implicito), ma la chiamata MyClass.new(var1 => $var1) su Ho passato un nome. Nota che detto metodo è l'unico .new() presente nella tua classe, quindi se la chiamata avesse effettivamente funzionato, avresti finito con una ricorsione infinita!

Problemi correlati