Search code examples
rigraph

Why is E(g) not identical to itself


Consider:

library(igraph)
g <- make_ring(3)

identical(g, g)    # TRUE as expected
# [1] TRUE

dput(E(g))
# structure(1:3, is_all = TRUE, class = "igraph.es", env = <weak reference>, graph = "4f82a4da-3975-11ef-8958-675a79d1d14f")


E(g) == E(g)              # test equality.
# [1] TRUE TRUE TRUE

all.equal(E(g), E(g))     # Next try.     
# [1] TRUE

identical(E(g), E(g), ignore.environment = FALSE) # Expecting TRUE.
# [1] FALSE

identical(E(g), E(g), ignore.environment = TRUE) # Expecting TRUE.
# [1] FALSE

Question: Why False?


Solution

  • Take a look at unclass(E(g)):

    [1] 1 2 3
    attr(,"is_all")
    [1] TRUE
    attr(,"env")
    <weak reference>
    attr(,"graph")
    [1] "a075a1af-ef79-4811-8876-3c0d2d45085f"
    

    It contains a "weak reference", which is an exotic R object that you rarely see. Each time you call E(g) you create a different weak reference, and so identical() says they are not identical.

    EDITED to add:

    You can read about weak references here: ?rlang::new_weakref. There are also notes here: http://homepage.divms.uiowa.edu/~luke/R/references/weakfinex.html, but it's not clear if they are current.

    The code that does the identical() comparison is here:

    https://github.com/wch/r-source/blob/ded6c7e0958844d6892c197009abe5879848ba4e/src/main/identical.c#L334-L335

    From the comment, it's not clear if the authors of those lines are sure it's doing the right thing. It would probably make more sense to say two weak references are identical if they reference the same object and have the same associated data and finalizer.