构造quines(自我复制功能)

Ben*_*ker 15 r quine

是否有人在R中构建了一个quine("一个程序,它生成一个自己的源文本副本作为其完整输出":http://www.nyx.net/~gthompso/quine.htm)?([quine]标签在Python,Java中提取了大量示例......但在R中显然没有.)

f <- function() { body() }
Run Code Online (Sandbox Code Playgroud)

接近:

> f()
{
    body()
}
Run Code Online (Sandbox Code Playgroud)

但缺少功能的名称.

最短的可能性怎么样?大多数混淆了吗?

编辑:从下面的各种答案中,似乎有多种方法来定义自我指涉性和必须发生的环境:

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

笔记:

  • 从R-帮助线程指出的@Spacedman(这似乎强调了简洁混淆)认为identical(quine,quine())是一个很好的测试案例,虽然它的棘手,因为环境相处携带:identical(quine,quine(),ignore.environment=TRUE)可能会更容易.
  • 最近(2015年10月)的博客文章提供了另一个答案......

Jos*_*ich 22

这是我能想到的最短的:

> "f" <- function() call("<-", "f", f)
> f()
"f" <- function () 
call("<-", "f", f)
Run Code Online (Sandbox Code Playgroud)


koh*_*ske 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
Run Code Online (Sandbox Code Playgroud)

可能这不是最短的.

更新:

略短的版本:

(function(x){cat(x,'(',d<-intToUtf8(0x0022),x,d,')',sep='')})("(function(x){cat(x,'(',d<-intToUtf8(0x0022),x,d,')',sep='')})")
Run Code Online (Sandbox Code Playgroud)


Jam*_*mes 6

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

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

哪个输出:

> f()
f <- function () 
{
    call("<-", as.name(as.character(sys.calls()[[1]])), sys.function(sys.parent()))
}
Run Code Online (Sandbox Code Playgroud)