Ответ 1
Это самое короткое, что я могу придумать:
> "f" <- function() call("<-", "f", f)
> f()
"f" <- function ()
call("<-", "f", f)
Кто-нибудь построил quine ( "Программа, которая генерирует копию собственного исходного текста в качестве своего полного вывода": http://www.nyx.net/~gthompso/quine.htm) в R? (Тег [quine] вытаскивает множество примеров в Python, Java,... но, по-видимому, ни один в R.)
f <- function() { body() }
близок:
> f()
{
body()
}
но не имеет имени функции.
Как насчет кратчайшей возможности? Большинство запутанных?
edit: из множества ответов ниже, кажется, что существует множество способов определить самореференцию и среду, в которой она должна произойти:
->
(@bill_080)->
[более или менее эквивалентна программе ->
text]: (@kohske)->
text (@JoshUlrich, @James, проблема, как определено выше)Примечания:
identical(quine,quine())
является хороший тестовый пример, хотя это сложно, потому что окружающая среда переносится вдоль: identical(quine,quine(),ignore.environment=TRUE)
может быть проще.Это самое короткое, что я могу придумать:
> "f" <- function() call("<-", "f", f)
> f()
"f" <- function ()
call("<-", "f", f)
Вот настоящий 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='')})")
Используя то, что 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()))
}
Если вы хотите функцию, которая возвращает функцию..... возможно, это?
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(...))
}
Хотя я не уверен, что это "считается" с точки зрения перспективы (я наткнулся на этот вопрос, пытаясь проверить, если он это делает), script
function(){}
выводит function(){}
. Это работает по тому же принципу, что и ответ Джошуа Ульриха, только что сведенный к делу.