2013-07-22 2 views
3

Есть ли эквивалент method_missing для R? Другими словами, возможно ли перехватить вызов несуществующего метода на объекте и что-то сделать с ним? Примеры для всех типов классов были бы замечательными (S3, S4, ссылочные классы). Что я хочу сделать, так это построить объект a, так что что-то вроде a$b было бы возможно без необходимости явно определять b.method_missing эквивалент в R

Edit: Это примерно, как я хотел бы мой объект вести:

setClass("myClass", representation(url = "character")) 
a <- new("myClass", url = "http://www.example.com") 
a$b$c 
# => 'http://www.example.com/b/c' 

Это классы S4, но любое предложение реализация приветствуется.

считает Oskar

+2

Возможно, вы захотите включить, используете ли вы S3, S4 или ссылочные классы (или если вы спрашиваете обо всех трех). – joran

+0

Кажется, что воспроизводимый пример поможет здесь. Я предполагаю, что вам нужно что-то более сложное, чем просто проверка вывода 'методов ('foo')' for 'foo.bar'? –

+0

Теперь я в замешательстве. 'a $ b' имеет мало общего с методами .... –

ответ

2

Для доступа a$b, да, это возможно - если неаккуратно. Причина в том, что $ - это просто оператор, который мы можем переопределить.

определение по умолчанию может быть получен следующим образом:

> `$` 
.Primitive("$") 

Это легко достаточновозможно изменить это так, что мы сначала проверить, действительно ли существует b в a$b. Вот грубый набросок (но только грубый набросок, смотри ниже):

`$` <- function (a, b) { 
    if (exists(as.character(substitute(b)), where = a)) 
     .Primitive("$")(a, b) 
    else 
     methodMissing(as.character(substitute(a)), as.character(substitute(b))) 
} 

... Теперь мы просто должны поставить methodMissing:

methodMissing <- function (a, b) 
    cat(sprintf('Requested missing %s on %s\n', b, a)) 

... и мы можем использовать его:

> foo <- list(bar = 'Hello') 
> foo$bar 
[1] "hello" 
> foo$baz 
Requested missing baz on foo 

Однако обратите внимание, что это интересно для других типов, например, оно больше не работает с кадрами данных:

> cars$speed 
NULL 

Я не знаю, является ли это тривиально, чтобы исправить это - это не достаточно, чтобы проверить на is.list(a), например - так действовать с осторожностью.

Решения для S3 и S4 оставлены в качестве упражнения для читателя (на самом деле, я понятия не имею - я не использую S4 и редко использую S3).

0

tryCatch должно быть эквивалентно method_missing, если я понял ваш вопрос правильно:

tryCatch(foo(options, named=option1,...), EXCEPTION-CLAUSE-HERE) 
Смежные вопросы