趣旨
わかってますよ、、、このニッチすぎる需要。
ですが、関数のコードをcharacter
データ(文字列)として取り扱えれば、コードの修正作業を{stringr}
とかに任せられたり、コードを保存し損ねた関数を取り出せるので、何とか標記の件を実現したかったわけです。
f1 <- function(){
print("正岡子規")
fx <- function(){cat("有名な\nやーつ\n")}
fx()
"a" %>%
print()
print(paste("柿食へば",
"鐘が鳴るなり",
"法隆寺"))
# 小峠ではない
}
やり方
試行錯誤の末、こういう方法を考えました。
自己流です。ご指摘ウェルカムです。
x <- paste(as.character(getSrcref(f1)), collapse = "\n")
はい、これだけです。
では実際に表示してみます。
> cat(x)
function(){
print("正岡子規")
fx <- function(){cat("有名な\nやーつ\n")}
fx()
"a" %>%
print()
print(paste("柿食へば",
"鐘が鳴るなり",
"法隆寺"))
# 小峠ではない
}
まったく同じものが取得できました!イェーイ
クラスもちゃんとfunction
からcharacter
になっています。
> class(f1)
[1] "function"
> class(x)
[1] "character"
余談1
getSrcref()
で取得したオブジェクトは一見文字列なのですが、実際はsrcref
という ちょっと何言ってるか分からない クラスのオブジェクトです。character
でもvector
でもないです。
それに関連して、as.character()
も厳密にはsrcref
クラスに適合したメソッドas.character.srcref()
を使うほうが安全ですが、総称的関数たるas.character()
を使っても全く問題ないです。
> class(getSrcref(f1))
[1] "srcref"
> as.character.srcref(getSrcref(f1))
[1] "function(){"
[2] " print(\"正岡子規\")"
[3] " fx <- function(){cat(\"有名な\\nやーつ\\n\")}"
[4] " fx()"
[5] " \"a\" %>% "
[6] " print() "
[7] " print(paste(\"柿食へば\", "
[8] " \"鐘が鳴るなり\", "
[9] " \"法隆寺\"))"
[10] " # 小峠ではない"
[11] "}"
余談2
srcref
オブジェクトを取得する方法は上記以外にもう一つあります。
> attributes(f1)[[1]]
一応クラスを確認すると、ちゃんとsrcref
クラスオブジェクトをゲットしてます。
> class(attributes(f1)[[1]])
[1] "srcref"
余談3
今まではc()
を使って抽出してきたのですが・・・
> cat(as.character(c(f1)))
function ()
{
print("正岡子規")
fx <- function() {
cat("有名な\nやーつ\n")
}
fx()
"a" %>% print()
print(paste("柿食へば", "鐘が鳴るなり", "法隆寺"))
}
おわかりいただけただろうか・・・。
- コード内の改行位置が元と異なる。
具体的には、引数毎の改行、パイプ演算子%>%
、{ggplot}
の+
毎の改行等は全て消えてしまう。 - 逆に大括弧
{}
の前後は強制的に改行してしまう。 -
#
のメモ書き等も消えてしまう。
という問題点があったので、どうにか解決できないかと試行錯誤しているうちに今回の方法を編み出しました。
おわりに
お試しあれ~~~。
Enjoy!
おしまい。