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.
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
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. –
punkt sprawiedliwy. Edytowałem mój oryginalny wpis. – RyanGrannell