Idiom for default S4 method? - r

Is there any agreed upon way of writing a fallback method for an S4 generic? I mean, if no signatures are matched, do you write a function to be used as default method that throws perhaps a message() explaining valid signatures? And what return value do you use? Or do you throw an error? Or do you do nothing at all and let R throw the usual error "unable to find an inherited method for function (...)".
Any recommendation?

Yes, there’s a agreed-on way, depending on whether a good default function already exists as a non-generic or not.
1. If there’s already a non-generic function that can serve as a default
Simply make it generic:
setGeneric('function_name')
2. If there’s no non-generic default function yet
Define a new generic
setGeneric(
'function_name',
function (object) {
standardGeneric('function_name')
}
)
Add a default implementation with catch-all parameters
setMethod(
'function_name',
signature(object = 'ANY'),
function (object) {
…
}
)

If you can write a generic that might plausibly work for a wide variety of possible classes, then it is common to do so. For example, the (S3) default method for terms tries to find a $terms component (or attribute — note that this includes the case when the argument is an S4 object with a #terms slot) in its first argument:
function (x, ...)
{
v <- x$terms
if (is.null(v)) {
v <- attr(x, "terms")
if (is.null(v))
stop("no terms component nor attribute")
}
v
}
(terms happens to be an S3 generic but there is no reason why it would not still behave this way if it were S4.)
If there is no sensible thing you can do then all you can really write for a default method is a function that accepts all the arguments in the signature of the generic (plus ... in case there are some methods that have extra arguments) and just calls stop with an error message along the lines of what you suggest.
In S3, you didn't need to do this — you could just not define the default method. This is the case with predict — if you call predict(2,3) say then you will get an error no applicable method for 'predict' applied to an object of class "c('double', 'numeric')". In S4, you will need to define such a default method yourself in the call to setGeneric.

Related

Is it possible to inherit from something other than the abstract type julia?

I have a function that I can't change and it expects type ExpectedType.
function some_function(some_parameter::ExpectedType)
....
some implementation
....
end
I want to pass my object of type OtherType.
I decided to inherit OtherType from ExpectedType.
struct OtherType <: ExpectedType end
But I'm getting an error: ERROR: invalid subtyping in definition of OtherType
Is it possible to inherit from non-abst types?
How can I get the functionality I need?
It is not possible to inherit from non-abstract type.
What I would typically do is writing a constructor for ExpectedType that takes OtherType as argument and then call some_function(ExpectedType(your_object)).
Also then you could define:
SourceModuleName.some_function(x::OtherType) = some_function(ExpectedType(x))
so that you do not have to call the constructor explicitly.

Unable to access object inside function using an external function R6

I have a R6 class with code like this
# Cutting out lots of code and only putting in relevant lines
public(
function1 <- function(){
var <- xyz$abc
},
function2 <- function(){
xyz <- blah blah
z <- function1()
}
)
When calling function2 I get an error in function1 saying that xyz is not found even though its assigned in function2 which is called before function1
Please let me know if I am understanding this correctly and how to fix it.
For "traditional" R functions the parent of the evaluation environment of a function is the calling environment.
For R6 function this not the same. The parent of the evaluation environment of a method is an environment enclosing the self variable that gives access to object properties.
You can test this by adding
print(ls(parent.env(environment()))) in your method.
This means that you can't have access to your xyz variable in function1. You must use public or private variables or pass it as a parameter to your function.
By the way you must also prepend self$ to the call of function1 (self$function1())

In R how to define a method with the same name in different S4 classes for a correct method dispatching

I've defined a method called "getValues" for a new S4 class in R. My class and method are:
myClass<-setClass("MyClass",
slots=list(a="numeric",b="list"))
setMethod("getValues", signature ( "MyClass", "missing", "missing"),
getValues<-function(x)
{
print("MyClass-getValues called")
})
The 'raster' package already has a method called 'getValues' but with different signatures (can be seen with showMethods("getValues")). So I thought method dispatching will select the correct method depending of the signature. But when I run:
a<-raster()
getValues(a) #problem: this calls "getValues" of the class 'MyClass' and prints "MyClass-getValues called"
I expected that the 'getValues' method for RasterLayer objects will be called, but this calls "getValues" of the class 'MyClass'!
Where is the error?
The error is in the commented line below:
myClass<-setClass("MyClass",
slots=list(a="numeric",b="list"))
setMethod("getValues", signature ( "MyClass", "missing", "missing"),
##getValues<-function(x)##
{
print("MyClass-getValues called")
})
This line overwrites the main definition of getValues as well as setting a method. Call this function anything other than getValues and it should work.

Passing QList as output argument reference

I have a function that return a bool to indicate if the process worked or not and i would like to have 2 outputs arguments passed to it by reference.
Here is the definition of my function:
bool LoadIndexes(QList<SourceIndex> &indexes, Logger &logger);
And here how i tried to use it:
QList<SourceIndex> indexes;
if (SourceIndex::LoadIndexes(indexes, logger)) { // logger is a member already instantiated
}
But i am getting an error call to non-static member function without an object argument related to my QList here and don't understand it.
I think your SourceIndex::LoadIndexes method is non-static method.

what is * return type in as3

I saw a method in Action script that has a return type of *
public function f(s:String):*
what does this [*] means ?
That answer is not 100% correct. There is no "untyped" and there is only a small difference between * and Object, because one could argue that Object means untyped as well since every type extends from Object.
However * implies the undefined value and Object not. A big difference! This is useful for dynamic languages because this means a property of an Object can be undefined which is different from defined and null.
So for instance y is undefined in { x: null } and x is defined but without a value. And you can make use of that:
var yesNoMaybe: *;
yesNoMaybe = true;
yesNoMaybe = false;
yesNoMaybe = undefined;
The * symbol means "untyped", meaning that the type can be anything (and that the value can be undefined). Using the asterisk has the same effect as not specifying the type at all, but it's good form to use it in order to be explicit about your intention. See the language reference for more info.

Resources