Hervé Pagès
2018-May-16 00:25 UTC
[Rd] Dispatch mechanism seems to alter object before calling method on it
Hi, This was quite unexpected: setGeneric("foo", function(x) standardGeneric("foo")) setMethod("foo", "vector", identity) foo(matrix(1:12, ncol=3)) # [1] 1 2 3 4 5 6 7 8 9 10 11 12 foo(array(1:24, 4:2)) # [1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 If I define a method for array objects, things work as expected though: setMethod("foo", "array", identity) foo(matrix(1:12, ncol=3)) # [,1] [,2] [,3] # [1,] 1 5 9 # [2,] 2 6 10 # [3,] 3 7 11 # [4,] 4 8 12 So, luckily, I have a workaround. But shouldn't the dispatch mechanism stay away from the business of altering objects before passed to it? Thanks, H. -- Herv? Pag?s Program in Computational Biology Division of Public Health Sciences Fred Hutchinson Cancer Research Center 1100 Fairview Ave. N, M1-B514 P.O. Box 19024 Seattle, WA 98109-1024 E-mail: hpages at fredhutch.org Phone: (206) 667-5791 Fax: (206) 667-1319
Michael Lawrence
2018-May-16 04:13 UTC
[Rd] Dispatch mechanism seems to alter object before calling method on it
My understanding is that array (or any other structure) does not "simply" inherit from vector, because structures are not vectors in the strictest sense. Basically, once a vector gains attributes, it is a structure, not a vector. The methods package accommodates this by defining an "is" relationship between "structure" and "vector" via an "explicit coerce", such that any "structure" passed to a "vector" method is first passed to as.vector(), which strips attributes. This is very much by design. Michael On Tue, May 15, 2018 at 5:25 PM, Herv? Pag?s <hpages at fredhutch.org> wrote:> Hi, > > This was quite unexpected: > > setGeneric("foo", function(x) standardGeneric("foo")) > > setMethod("foo", "vector", identity) > > foo(matrix(1:12, ncol=3)) > # [1] 1 2 3 4 5 6 7 8 9 10 11 12 > > foo(array(1:24, 4:2)) > # [1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 > 24 > > If I define a method for array objects, things work as expected though: > > setMethod("foo", "array", identity) > > foo(matrix(1:12, ncol=3)) > # [,1] [,2] [,3] > # [1,] 1 5 9 > # [2,] 2 6 10 > # [3,] 3 7 11 > # [4,] 4 8 12 > > So, luckily, I have a workaround. > > But shouldn't the dispatch mechanism stay away from the business of > altering objects before passed to it? > > Thanks, > H. > > -- > Herv? Pag?s > > Program in Computational Biology > Division of Public Health Sciences > Fred Hutchinson Cancer Research Center > 1100 Fairview Ave. N, M1-B514 > P.O. Box 19024 > Seattle, WA 98109-1024 > > E-mail: hpages at fredhutch.org > Phone: (206) 667-5791 > Fax: (206) 667-1319 > > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel >
Hervé Pagès
2018-May-16 15:33 UTC
[Rd] Dispatch mechanism seems to alter object before calling method on it
On 05/15/2018 09:13 PM, Michael Lawrence wrote:> My understanding is that array (or any other structure) does not > "simply" inherit from vector, because structures are not vectors in > the strictest sense. Basically, once a vector gains attributes, it is > a structure, not a vector. The methods package accommodates this by > defining an "is" relationship between "structure" and "vector" via an > "explicit coerce", such that any "structure" passed to a "vector" > method is first passed to as.vector(), which strips attributes. This > is very much by design.It seems that the problem is really with matrices and arrays, not with "structures" in general: f <- factor(c("z", "x", "z"), levels=letters) m <- matrix(1:12, ncol=3) df <- data.frame(f=f) x <- structure(1:3, titi="A") Only the matrix looses its attributes when passed to a "vector" method: setGeneric("foo", function(x) standardGeneric("foo")) setMethod("foo", "vector", identity) foo(f) # attributes are preserved # [1] z x z # Levels: a b c d e f g h i j k l m n o p q r s t u v w x y z foo(m) # attributes are stripped # [1] 1 2 3 4 5 6 7 8 9 10 11 12 foo(df) # attributes are preserved # f # 1 z # 2 x # 3 z foo(x) # attributes are preserved # [1] 1 2 3 # attr(,"titi") # [1] "A" Also if structures are passed to as.vector() before being passed to a "vector" method, shouldn't as.vector() and foo() be equivalent on them? For 'f' and 'x' they're not: as.vector(f) # [1] "z" "x" "z" as.vector(x) # [1] 1 2 3 Finally note that for factors and data frames the "vector" method gets selected despite the fact that is( , "vector") is FALSE: is(f, "vector") # [1] FALSE is(m, "vector") # [1] TRUE is(df, "vector") # [1] FALSE is(x, "vector") # [1] TRUE Couldn't we recognize these problems as real, even if they are by design? Hopefully we can all agree that: - the dispatch mechanism should only dispatch, not alter objects; - is() and selectMethod() should not contradict each other. Thanks, H.> > Michael > > > On Tue, May 15, 2018 at 5:25 PM, Herv? Pag?s <hpages at fredhutch.org> wrote: >> Hi, >> >> This was quite unexpected: >> >> setGeneric("foo", function(x) standardGeneric("foo")) >> >> setMethod("foo", "vector", identity) >> >> foo(matrix(1:12, ncol=3)) >> # [1] 1 2 3 4 5 6 7 8 9 10 11 12 >> >> foo(array(1:24, 4:2)) >> # [1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 >> 24 >> >> If I define a method for array objects, things work as expected though: >> >> setMethod("foo", "array", identity) >> >> foo(matrix(1:12, ncol=3)) >> # [,1] [,2] [,3] >> # [1,] 1 5 9 >> # [2,] 2 6 10 >> # [3,] 3 7 11 >> # [4,] 4 8 12 >> >> So, luckily, I have a workaround. >> >> But shouldn't the dispatch mechanism stay away from the business of >> altering objects before passed to it? >> >> Thanks, >> H. >> >> -- >> Herv? Pag?s >> >> Program in Computational Biology >> Division of Public Health Sciences >> Fred Hutchinson Cancer Research Center >> 1100 Fairview Ave. N, M1-B514 >> P.O. Box 19024 >> Seattle, WA 98109-1024 >> >> E-mail: hpages at fredhutch.org >> Phone: (206) 667-5791 >> Fax: (206) 667-1319 >> >> ______________________________________________ >> R-devel at r-project.org mailing list >> https://urldefense.proofpoint.com/v2/url?u=https-3A__stat.ethz.ch_mailman_listinfo_r-2Ddevel&d=DwIFaQ&c=eRAMFD45gAfqt84VtBcfhQ&r=BK7q3XeAvimeWdGbWY_wJYbW0WYiZvSXAJJKaaPhzWA&m=gynT4YhbmVKZhnX4srXlCWZZRyVBMXG211CKgftdEs0&s=_I0aFHQVnXdBfB5kTLg9TxK_2LHdSuaB6gqZwSx1orQ&e>>-- Herv? Pag?s Program in Computational Biology Division of Public Health Sciences Fred Hutchinson Cancer Research Center 1100 Fairview Ave. N, M1-B514 P.O. Box 19024 Seattle, WA 98109-1024 E-mail: hpages at fredhutch.org Phone: (206) 667-5791 Fax: (206) 667-1319
Apparently Analagous Threads
- Dispatch mechanism seems to alter object before calling method on it
- Dispatch mechanism seems to alter object before calling method on it
- Dispatch mechanism seems to alter object before calling method on it
- selectMethod() can fail to find methods in situations of multiple dispatch
- selectMethod() can fail to find methods in situations of multiple dispatch