2013-06-23 9 views
6

Próbuję napisać funkcję, która przechwytuje argumenty funkcji, z której jest wywoływana. Na przykład,uzyskiwanie argumentów funkcji nadrzędnej w R, o nazwach

get_args <- function() as.list(sys.call(sys.parent()))[-1] 

caller <- function (x, y, z) { 
    get_args() 
} 
caller(1,2,3) 

[[1]] 
[1] 1 

[[2]] 
[1] 2 

[[3]] 
[1] 3 

sys.call() niestety nie dodaje nazwy parametrów meczu z wartościami argumentu i chciałbym napisać podobną wersję get_args zwracającą wynik podobny do

caller2 <- function (x, y, z) { 
    as.list(match.call())[-1] 
} 
caller2(1,2,3) 

$x 
[1] 1 

$y 
[1] 2 

$z 
[1] 3 

zastąpienie "get_args()" przez "match.call()" bezpośrednio nie jest rozwiązaniem, którego szukam, ponieważ w rzeczywistości get_args zrobi kilka innych rzeczy zanim zwróci argumenty funkcji nadrzędnej.

Próbowałem użyć match.call() z sys.parent() na kilka sposobów, ale nie mogę uzyskać funkcji, aby zwrócić argumenty wywołującego; po prostu zwraca argumenty get_args().

Czy istnieje sposób, aby get_args() zwrócił wynik identyczny z caller2 dla powyższego przypadku testowego? Wiem, że ręczne nazywanie argumentów jest możliwe przy użyciu formals(), ale czy to gwarantuje ekwipunek?

Jeśli potrzebujesz wyjaśnienia, zostaw komentarz poniżej. Dzięki.

EDIT 1:

cel get_args() ma działać jako przyjazny dla użytkownika sposób na uzyskanie argumenty z którego funkcja została wywołana. Wpisanie as.list (match.call()) [- 1] zestarzeje się, ale ponieważ match.call chwyta najbliższe wywołanie funkcji, otrzymuje po prostu argumenty get_args().

get_args() również dostanie domyślne argumenty z funkcji nadrzędnej, ale jest to łatwe do wdrożenia.

ROZWIĄZANIE:

dzięki Hong Ooi, kluczem do korzystania match.call wydaje się być zapewnienie zarówno połączenia i definicji funkcji, którą chcesz dowiedzieć się o. Nieco zmodyfikowane, anonimowy Wersja z get_args jest poniżej dla potomnych

get_args <- function() { 
as.list(match.call(
    def = sys.function(-1), 
    call = sys.call(-1)))[-1] 

} 

Ta wersja znajdzie funkcję dalej w górę stosu wywołań, chwyta swoją definicję i zadzwonić, i dopasowuje parametry do swoich argumentów.

Odpowiedz

8
get_args <- function() 
{ 
    cl <- sys.call(-1) 
    f <- get(as.character(cl[[1]]), mode="function", sys.frame(-2)) 
    cl <- match.call(definition=f, call=cl) 
    as.list(cl)[-1] 
} 

Kluczem tutaj jest, aby ustawić definition argument match.call być get_arg „s funkcji wywołującej. Powinno to (miejmy nadzieję!) Działać w ogólnym przypadku, w którym get_args może być wywoływany z dowolnego miejsca.

+0

interesująca odpowiedź, ale niestety get_args musi być argumentem o zmiennej zero. Zgadzam się, że taka droga ułatwiłaby życie, ale funkcja (choć z wieloma modyfikacjami) będzie używana w kodzie produkcyjnym dla CRAN, który nie pozwoli na wewnętrzne połączenia. – RyanGrannell

+0

Zobacz moją edycję, aby usunąć argumenty z 'get_call'. Nadal nie widzę powodu, dla którego potrzebna jest funkcja niestandardowa. Może powinieneś opublikować podstawowy problem jako nowe pytanie, a ludzie mogą pomóc ci rozwiązać go w sposób, który nie wymaga mimingu językowego. –

+0

punkt sprawiedliwy. Edytowałem mój oryginalny wpis. – RyanGrannell

Powiązane problemy