奎因

奎因程序,或称奎因,是一种在执行时能打印自身源代码的程序。 奎因程序不得 "跳出自身",例如打印其所在文件的内容,或使用内省功能打印自身表示。 相反,它必须计算自身的源代码。


创建此类程序的经典方法有两个步骤:

  1. 用插值占位符初始化一个字符串变量。
  2. 打印字符串并将其插值到自身

诀窍在于使字符串恰到好处。 如何做到这一点因语言而异,取决于变量的声明、分号和换行的需要、所需的引号等。

巴什

与 Bash 中的大多数程序一样,该程序使用了一个有趣的怪癖。 虽然单引号是强引号,不会扩展任何内容,但 printf 八进制转义字符作为指定码位的字符:

s='s=%s;printf "$s" "$s"';printf "$s" "$s"

Python

在 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 提供了在格式化打印宏中引用参数的方法,但该宏要求打印宏的第一个参数是字符串字面量!因此,最好使用位置参数标识符:

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+

最后是由 Cliff Biffle 开发的 HQ9+:

Q
背部