Ett Quine-program eller Quine är ett program som matar ut sin egen källkod när det körs. En Quine får inte "träda utanför sig själv" genom att till exempel skriva ut innehållet i filen som innehåller den eller använda introspektiva förmågor för att skriva ut sin egen representation. Istället måste den beräkna sin egen källkod.
Det klassiska sättet att skapa ett sådant program sker i två steg:
- Initiera en strängvariabel med en platshållare för interpolation.
- Skriv ut strängen och interpolera den i sig själv .
Tricket är att få strängen precis rätt. Hur man gör detta varierar från språk till språk och beror på hur variabeln deklareras, behovet av semikolon och nyrader, vilka citattecken som krävs osv. Användningen av citattecken är intressant; Man måste hitta ett sätt att indikera att ett citattecken ska skrivas ut utan att faktiskt använda citattecken.
Våldsamt slag
Som de flesta saker i Bash använder det här programmet en intressant egenhet. Även om enstaka citat är starka citat och inte utökar någonting, tolkat printf
oktala escape-tecken som tecken med angiven kodpunkt:
s='s=%s;printf "$s" "$s"';printf "$s" "$s"
Pytonorm
I Python returnerar formatspecifikationen %r
automatiskt enstaka citat. Det är enklast om koden slutar med ett nyradstecken:
s='s=%r;print(s%%s)';print(s%s)
Om du vill ha koden utan radbrytningar måste du skriva följande:
s='s=%r;print(s%%s,sep="")';print(s%s,sep="")
JavaScript
Följande JavaScript-quines körs under node.js. du använder console.log
, som alltid lägger till en ny rad, så en ny rad behövs i slutet av varje skript:
s="s=%j;console.log(s,s)";console.log(s,s)
Följande program är också intressant: det skriver inte ut hela representationen, men det bygger på det faktum att funktioner har en viss representation:
(function a(){console.log('('+a+')()')})()
Nästa exempel är nära att fuska eftersom det eval
begagnad:
code='var q=unescape("%27");console.log("code="+q+code+q+";eval(code)")';eval(code)
Rost
Rust ger ett sätt att omsluta ett argument inom citattecken i dess formaterade utskriftsmakro. Detta makro kräver dock att det första argumentet för utskriftsmakrot är en bokstavlig sträng! Det är därför bäst att använda positionsargumentidentifieraren:
fn main(){print!("fn main(){{print!({0:?},{0:?})}}","fn main(){{print!({0:?},{0:?})}}")}
PHP
Detta PHP-program fungerar genom att lagra källkoden i en sträng och sedan använda den strängen printf
utgångar. De 39
står för ASCII-tecknet '
, för att korrekt hantera citattecken i strängen:
<?php
$code = '<?php
$code = %c%s%c;
printf($code, 39, $code, 39);
';
printf($code, 39, $code, 39);
HQ9+
Sist men inte minst är HQ9+, utvecklat av Cliff Biffle:
Q