Un programma quine, o quine, è un programma che stampa il proprio codice sorgente quando viene eseguito. Un quine non deve "uscire da se stesso", ad esempio stampando il contenuto del file in cui è contenuto o utilizzando le capacità introspettive per stampare la propria rappresentazione, ma deve calcolare il proprio codice sorgente.
Il modo classico per creare un programma di questo tipo è in due fasi:
- Inizializza una variabile stringa con un segnaposto per l'interpolazione.
- Stampa la stringa e la interpola in se stessa.
Il trucco consiste nell'ottenere la stringa giusta. Il modo in cui farlo varia da lingua a lingua e dipende dalla dichiarazione delle variabili, dalla necessità di punti e virgole e interruzioni di riga, dalle virgolette richieste, ecc.
Bash
Come la maggior parte delle cose in Bash, questo programma utilizza un'interessante stranezza: sebbene le virgolette singole siano virgolette forti e non espandano nulla, l'opzione printf
caratteri di escape ottali come caratteri con il punto di codice specificato:
s='s=%s;printf "$s" "$s"';printf "$s" "$s"
Pitone
In Python, l'identificatore di formato %r
Il modo più semplice per farlo è quello di terminare il codice con un carattere newline:
s='s=%r;print(s%%s)';print(s%s)
Se si vuole il codice senza interruzione di riga, si deve scrivere quanto segue:
s='s=%r;print(s%%s,sep="")';print(s%s,sep="")
JavaScript
Le seguenti quine JavaScript vengono eseguite sotto node.js e usano console.log
, che aggiunge sempre una nuova riga, in modo che sia richiesta una nuova riga alla fine di ogni script:
s="s=%j;console.log(s,s)";console.log(s,s)
Anche il programma seguente è interessante: non stampa la sua intera rappresentazione, ma si basa sul fatto che le funzioni hanno una rappresentazione specifica:
(function a(){console.log('('+a+')()')})()
L'esempio successivo è prossimo all'imbroglio, in quanto eval
usato:
code='var q=unescape("%27");console.log("code="+q+code+q+";eval(code)")';eval(code)
Ruggine
Rust fornisce un modo per citare un argomento nella sua macro di stampa formattata, ma questa macro richiede che il primo argomento della macro di stampa sia un letterale di stringa! È quindi meglio usare l'identificatore posizionale di argomento:
fn main(){print!("fn main(){{print!({0:?},{0:?})}}","fn main(){{print!({0:?},{0:?})}}")}
PHP
Questo programma PHP funziona salvando il codice sorgente in una stringa di caratteri e poi usando printf
Il 39
indica il carattere ASCII '
, per gestire correttamente le virgole invertite della stringa:
<?php
$code = '<?php
$code = %c%s%c;
printf($code, 39, $code, 39);
';
printf($code, 39, $code, 39);
HQ9+
Ultimo ma non meno importante è HQ9+, sviluppato da Cliff Biffle.:
Q