HenrikBengtsson / R.oo

R package: R.oo - R Object-Oriented Programming with or without References
https://cran.r-project.org/package=R.oo
20 stars 1 forks source link

Object finalizer() method defined in a local environment is not being called #4

Closed HenrikBengtsson closed 9 years ago

HenrikBengtsson commented 9 years ago

EXAMPLE:

library("R.oo")

setConstructorS3("Foo", function() {
  extend(Object(), "Foo")
})

setMethodS3("finalize", "Foo", function(this, ...) {
  cat("Finalized Foo\n")
})

x <- Foo()
print(x)

# Trigger finalizer via garbage collection
rm(list="x")
gc()

local({

setConstructorS3("Bar", function() {
  extend(Object(), "Bar")
})

setMethodS3("finalize", "Bar", function(this, ...) {
  cat("Finalized Bar\n")
})

x <- Bar()
print(x)

# Trigger finalizer via garbage collection
rm(list="x")
gc()

})

will output

[1] "Foo: 0x000000000baecb78"
Finalized Foo
[1] "Bar: 0x000000001007c000"

Note how the Bar finalizer is never called.

HenrikBengtsson commented 9 years ago

This is because the registered finalizer calls finalize(<object)> via the generic function (defined in R.oo), which in turn dispatches on class. It is not documented from within which environment the finalizer is called, but I'm pretty sure it's the global environment (recalled from some private emails with R core). Since finalize() for Bar is in a local environment, this will never be found/dispatched on. Hence, the finalize() call will fall back to the default one for Object which does nothing.

I'm not sure if there is another solution to this, unless one ties the finalizer to the actual object.

HenrikBengtsson commented 9 years ago

This one does not seem to be solvable under the current design. Leaving it as is for now.