2016-05-24 26 views
8

sqrt possono essere chiamati tramite la funzione sintassi:Definire una subroutine che può essere chiamato tramite sintassi del metodo

> sqrt 16 
4 

Può anche essere chiamato tramite il metodo sintassi:

> 16.sqrt 
4 

C'è un modo per rendere subroutine definite dall'utente richiamabili tramite la sintassi del metodo?

Per esempio, definiamo sq:

> sub sq(Int $n) { $n*$n } 
sub sq (Int $n) { #`(Sub|64042864) ... } 
> sq 4 
16 

Esiste un modo per renderlo richiamabile come un metodo? Cioè

> 4.sq 

risposta

9

C'è un modo per rendere utenti subroutine definite richiamabile tramite sintassi del metodo?

Sì, basta usare la sintassi .&, come in:

625.&sqrt.say 
# 25 

L'invocant viene passato come primo argomento:

sub sq { $^a² }; say 4.&sq 
4.&sq.say 
# 16 

L'unico problema che si è dovuto usare unspace se vuoi suddividere la catena di metodi con questi in più righe:

4.&sq\ 
.&sq.say; 
+0

Grazie, Zoffix! – dharmatech

+1

'125. & sqrt.say' potrebbe essere' 625. & sqrt.say' per rendere '25' la risposta giusta? – Bugfinger

4

È possibile utilizzare scimmia-tipizzazione per aumentare Int. Aspettatevi che l'ottimizzatore vada in cauzione, che le vostre willy/tette si restringano e che il mondo finisca in generale. Scimmia è il male. Non usarlo a meno che non sia necessario.

use MONKEY-TYPING; 
augment class Int { method sq(Int:D $i:){ $i * $i } }; 
my Int $i = 4; 
say $i.sq; 

È possibile mescolare un ruolo all'oggetto. Si noti che l'oggetto è l'oggetto, non la classe Int né il contenitore $i.

my $i = 4 but role :: { method sq(Int:D $i:){ $i * $i } }; 
say $i.sq; 

è possibile creare un metodo di flottante libero e utilizzare .& operatore di chiamata di metodo.

my method sq(Int:D $i:){ $i * $i }; 
my $i = 4; 
say $i.&sq; 

EDIT:

Se si vuole veramente rompere le ipotesi si può anche accedere agli attributi privati.

class Foo { has $!bar = 'meow'; }; 
use MONKEY-TYPING; 
augment class Foo { method baz { say $!bar } }; 
Foo.new.baz 
# OUTPUT«meow␤» 
+0

Grazie gfldex! Sono sorpreso di vedere che questo non sembra essere ben supportato. – dharmatech

+0

@dharmatech se non si sente ben supportato allora la tua soluzione potrebbe non adattarsi al problema che hai. A meno che non forniate dettagli sul perché volete aggiungere un metodo dall'esterno a una classe, nessuno può darvi un buon consiglio. Perl 6 utilizza i moduli precompilati. Se si aumenta una classe che viene utilizzata da un tale modulo, il compilatore potrebbe dover ricompilare quel modulo, innescando una catena piuttosto lunga di lentezza. Perl 6 ha lo scopo di fornire un compilatore con un numero sufficiente di codice byte by rope to nit. Questo ha un prezzo. –

+0

Vorrei aggiungere che l'esempio di 'augment class' consente l'accesso agli attributi privati ​​di quella classe, mentre tutti gli altri esempi no. –