Clojure

finalize won't work in reified objects - document

Details

  • Type: Enhancement Enhancement
  • Status: Open Open
  • Priority: Minor Minor
  • Resolution: Unresolved
  • Affects Version/s: Release 1.5, Release 1.6
  • Fix Version/s: None
  • Component/s: None
  • Labels:
    None
  • Environment:
    java 7

Description

Finalize is called for reified objects even when they are still reachable. It gets called second time at proper time.

user=> (def x (reify Object (finalize [o] (println "OH MY!"))))
#'user/x
user=> (System/gc)
nil
OH MY!
user=> x
#<user$reify__1496 user$reify__1496@53fb35af>
user=> (System/gc)
nil
user=> (def x nil)
#'user/x
user=> (System/gc)
nilOH MY!

Deftype seems to work fine

user=> (deftype T [] Object (finalize [o] (println "great success")))
user.T
user=> (def y (->T))
#'user/y
user=> (System/gc)
nil
user=> (def y nil)
#'user/y
user=> (System/gc)
great success

Activity

Hide
Alex Miller added a comment -

Just a note: the calls to System/gc don't necessarily cause finalizers to run on the first try - sometimes it took more than one for that to succeed for me. You'd think System/runFinalizers would do it but I had no luck at all with that.

Show
Alex Miller added a comment - Just a note: the calls to System/gc don't necessarily cause finalizers to run on the first try - sometimes it took more than one for that to succeed for me. You'd think System/runFinalizers would do it but I had no luck at all with that.
Hide
Gary Fredericks added a comment -

reify actually creates two objects – the first is created by reify*, and then reify immediately calls with-meta on it, creating a copy.

The docstring sort of describes this behavior: "reify always implements clojure.lang.IObj and transfers meta data of the form to the created object."

Show
Gary Fredericks added a comment - reify actually creates two objects – the first is created by reify*, and then reify immediately calls with-meta on it, creating a copy. The docstring sort of describes this behavior: "reify always implements clojure.lang.IObj and transfers meta data of the form to the created object."
Hide
Jozef Wagner added a comment -

Oh, so finalizer is a no-no in reify. Should be mentioned in docs IMO.

Show
Jozef Wagner added a comment - Oh, so finalizer is a no-no in reify. Should be mentioned in docs IMO.
Hide
Gary Fredericks added a comment -

Just for fun you could do something tricksy like:

^::second-object
(reify Object
  (finalize [self]
    (when (::second-object (meta self))
      ...)))

(have not actually run this)

Show
Gary Fredericks added a comment - Just for fun you could do something tricksy like:
^::second-object
(reify Object
  (finalize [self]
    (when (::second-object (meta self))
      ...)))
(have not actually run this)
Alex Miller made changes -
Field Original Value New Value
Priority Major [ 3 ] Minor [ 4 ]
Issue Type Defect [ 1 ] Enhancement [ 4 ]
Summary Finalize is called for reified objects even when they are still reachable finalize won't work in reified objects - document
Hide
Gary Fredericks added a comment -

It looks like the class generated by reify always has a constructor that takes a metadata argument, so it doesn't seem out of the question to eliminate the extra object altogether.

I'll try to keep digging on this.

Show
Gary Fredericks added a comment - It looks like the class generated by reify always has a constructor that takes a metadata argument, so it doesn't seem out of the question to eliminate the extra object altogether. I'll try to keep digging on this.

People

Vote (0)
Watch (3)

Dates

  • Created:
    Updated: