ソースファイルからの関数定義の抽出
TL上で,Rのソースファイルから関数定義を抽出できないかが話題になっていたので,暫定案のご提示.
以下では,対処案を示すことを優先しているため,最小限の解説しかしていない.
ソースコードは,githubに上げたので適宜参照のこと.
source関数を読み解く
Rでソースファイルを読み込んでパースするsource関数は,リンク先の"source_orig.r"のように定義されている.
ここで注目すべきは,214-218行目である.
yyというのは,ソースコード内の式を評価したもので,値(value)とオブジェクトの内容を表示するかどうかを指定する論理値(visible)から構成される.
print.eval引数が真,かつ yy$visibleが真のとき,オブジェクトの内容が表示される仕様になっている.
if (print.eval && yy$visible) { if (isS4(yy$value)) methods::show(yy$value) else print(yy$value) }
しかし,Rの標準のsource関数の仕様だと,上記のyy$visibleが偽となり上記のコードが実行されないため,関数の本体も表示されることはない.
仕様を変更して関数を出力する
リンク先の"my_source.r" 217-220行目にあるように,上記の箇所を次のように書き換えればよい.
print.eval引数が真のとき,かつ,式であるeiオブジェクトを評価すると関数であるとき,関数の定義が出力されるようにする.
if (print.eval && is.function(eval(ei))) { print(ei[[1]]) message("") }
このように変更した関数名もmy.sourceとして,"my_source.r"というファイル名で保存しておく.
次のようなソースコードを用意して,これをmy.source関数で読み込もう.
test.r
hoge <- function() { } huga <- function() { } a <- 1 b <- 5 hoge()
問題なく動けば,hoge関数とhuga関数が表示されるはずである.
> source("my_source.r"); my.source("test.r", print.eval=TRUE) hoge <- function() { } huga <- function() { }
関数のカッコの位置などが変わってしまっているなど課題は多いが,ひとまず所望の動作が得られた.
== 追記 ==
@kos59125さんにもっと簡便な方法をご教示いただいた.
@kos59125さんのgistにあるように,parse関数でソースファイルをパースして式をリストにして,評価すると関数のものだけをフィルターするという発想.
> Filter(function(e) is.function(eval(e)), as.list(parse("test.r", keep.source=TRUE))) [[1]] hoge <- function() { } [[2]] huga <- function() { }