15

有没有人在 R 中构建了一个 quine(“一个生成自己的源文本副本作为其完整输出的程序”:http ://www.nyx.net/~gthompso/quine.htm )?([quine] 标签在 Python、Java 中提供了很多示例……但在 R 中显然没有。)

f <- function() { body() }

接近:

> f()
{
    body()
}

但缺少函数的名称。

最短的可能性如何?最糊涂?

编辑:从下面的各种答案来看,似乎有多种方法可以定义自我参照性及其必须发生的环境:

  • 在 R 环境中:函数->函数 (@bill_080)
  • 在 OS/shell 环境中:程序->程序 [或多或少等同于程序->文本]:(@kohske)
  • 其他:函数->文本(@JoshUlrich,@James,上面定义的问题)

笔记:

  • @Spacedman 指出的来自 R-help的线程(似乎强调混淆而不是简洁)表明这identical(quine,quine())是一个很好的测试用例,尽管它很棘手,因为环境可以进行:identical(quine,quine(),ignore.environment=TRUE)可能更容易。
  • 最近(2015 年 10 月)的一篇博文提供了另一个答案……
4

5 回答 5

22

这是我能想到的最短的:

> "f" <- function() call("<-", "f", f)
> f()
"f" <- function () 
call("<-", "f", f)
于 2011-06-27T17:23:29.997 回答
21

这是一个真正的 Quine,它是一个程序(不是函数),它生成自己的源文本的副本作为其完整输出。

在控制台上,

# y1.R is a quine program
$ cat y1.R
(function(x){cat(x);cat('(');cat(intToUtf8(0x0022));cat(x);cat(intToUtf8(0x0022));cat(')')})("(function(x){cat(x);cat('(');cat(intToUtf8(0x0022));cat(x);cat(intToUtf8(0x0022));cat(')')})")

# execute y1.R and show output
$ /usr/bin/R --vanilla --slave < y1.R
(function(x){cat(x);cat('(');cat(intToUtf8(0x0022));cat(x);cat(intToUtf8(0x0022));cat(')')})("(function(x){cat(x);cat('(');cat(intToUtf8(0x0022));cat(x);cat(intToUtf8(0x0022));cat(')')})")

# save the output of the execution of y1
$ /usr/bin/R --vanilla --slave < y1.R > y2.R

# compare input and output -- exactly same.
$ diff y1.R y2.R

可能这不是最短的。

更新:

和稍短的版本:

(function(x){cat(x,'(',d<-intToUtf8(0x0022),x,d,')',sep='')})("(function(x){cat(x,'(',d<-intToUtf8(0x0022),x,d,')',sep='')})")
于 2011-06-27T18:25:19.063 回答
6

使用什么body作为灵感,call可以用来重现调用命令:

f <- function () 
{
    call("<-", as.name(as.character(sys.calls()[[1]])), sys.function(sys.parent()))
}

哪个输出:

> f()
f <- function () 
{
    call("<-", as.name(as.character(sys.calls()[[1]])), sys.function(sys.parent()))
}
于 2011-06-27T16:48:07.840 回答
1

如果你想要一个返回函数的函数......也许是这个?

junk <- function(...) {
  function(...) {
    structure(junk(...))
  }
}

输出是:

> junk()

function(...) {
    structure(junk(...))
  }
<environment: 01ef8e50>


> boo <- junk(999)
> boo

function(...) {
    structure(junk(...))
  }
<environment: 020e1048>


>dput(boo)

function (...) 
{
    structure(junk(...))
}
于 2011-06-27T17:15:02.223 回答
1

虽然我不确定从 quine 的角度来看这是否“重要”(我在尝试验证是否存在时偶然发现了这个问题),但脚本

function(){}

将输出function(){}. 这与 Joshua Ulrich 的回答原理相同,只是精简到了要点。

于 2015-11-03T21:47:56.633 回答