クィーン・プログラム(クィーン)とは、実行されるとそれ自身のソース・コードを出力するプログラムのことである。 クィーンは、例えば、それが含まれているファイルの内容を出力したり、内省的な機能を使ってそれ自身の表現を出力したりするなど、「それ自身の外側に踏み出す」ものであってはならない。 その代わりに、それ自身のソース・コードを計算しなければならない。
このようなプログラムを作成する古典的な方法は、次の2ステップである。:
- 補間用のプレースホルダを持つ文字列変数を初期化する。
- 文字列を表示し、それ自身を補間する。
そのコツは、文字列を適切に配置することである。 その方法は言語によって異なり、変数の宣言、セミコロンや改行の必要性、必要な引用符などに依存する。引用符の扱いは興味深く、実際に引用符を使わずに引用符を表示する方法を見つけなければならない。
バッシュ
Bash のほとんどのものと同様に、このプログラムも面白い癖を使っています。 シングルクォートは強い引用符で、何も展開しませんが printf
8進エスケープ文字を、指定されたコードポイントを持つ文字として使用する。:
s='s=%s;printf "$s" "$s"';printf "$s" "$s"
パイソン
Python では、フォーマット識別子 %r
コードが改行文字で終わるのが最も簡単です。:
s='s=%r;print(s%%s)';print(s%s)
改行せずにコードを書きたい場合は、次のように記述する必要がある。:
s='s=%r;print(s%%s,sep="")';print(s%s,sep="")
JavaScript
以下のJavaScriptクィーンはnode.jsで動作します。 console.log
, これは常に改行を追加するので、各スクリプトの最後には改行が必要である。:
s="s=%j;console.log(s,s)";console.log(s,s)
次のプログラムも興味深い。これは、その表現全体を印刷するのではなく、関数が特定の表現を持っているという事実に依存している。:
(function a(){console.log('('+a+')()')})()
次の例は不正行為に近い。 eval
中古:
code='var q=unescape("%27");console.log("code="+q+code+q+";eval(code)")';eval(code)
さび
Rustは、書式付きprintマクロで引数を引用する方法を提供していますが、このマクロは、printマクロの最初の引数が文字列リテラルであることを要求します! したがって、位置引数識別子:
fn main(){print!("fn main(){{print!({0:?},{0:?})}}","fn main(){{print!({0:?},{0:?})}}")}
PHP
このPHPプログラムは、ソースコードを文字列で保存し、次に printf
について 39
はASCII文字 '
, 文字列中の逆カンマを正しく処理するために:
<?php
$code = '<?php
$code = %c%s%c;
printf($code, 39, $code, 39);
';
printf($code, 39, $code, 39);
HQ9+
最後に紹介するのは、クリフ・ビッフルが開発したHQ9+だ。:
Q