C bindings and finalize

Hi there.

Next code involving C bindings for Hunspell library.

lib LibHunspell
  type Hunhandle = Void*

  fun create = Hunspell_create(affpath : LibC::Char*, dpath : LibC::Char*) : Hunhandle
  fun destroy = Hunspell_destroy(p_hunspell : Hunhandle)
  fun spell = Hunspell_spell(p_hunspell : Hunhandle, x1 : LibC::Char*) : LibC::Int

class Hunspell
  @handle : LibHunspell::Hunhandle

  def initialize(affpath : String, dpath : String)
    @closed = false
    @handle = LibHunspell.create(affpath, dpath) # => Pointer(Void)

  def spellcheck(word : String) : Bool
    LibHunspell.spell(@handle, word) != 0

  def finalize
    puts "__finalize__"

  def close
    LibHunspell.destroy(@handle) unless @closed
    @closed = true

loop do
  hunspell = Hunspell.new("/usr/share/hunspell/en_US.aff", "/usr/share/hunspell/en_US.dic")
  # hunspell.close

You can notice finalize method is never called.
Of course, I can call the close method manually so this is not an issue at all for me.
I’m just curious does Crystal have a natural way to do this automatically?
Thanks for any advice.


I just ran it, the finalize method is called. Can you print something else in the loop to make sure the program is actually running?

Hm, interesting.

puts hunspell.spellcheck("d0g")

Yes, is actually running in a loop.

Maybe it’s Hunspell issue.
What OS and Hunspell version are you using?


I forget that the GC running after some time (around 20sec in this case).

What is more interesting. On macOS everything is ok.

crystal -v
Crystal 0.36.0 (2021-01-26)

LLVM: 9.0.1
Default target: x86_64-apple-macosx

But on Ubuntu 20.04 finalize method is never called. This is really weird.

crystal -v                     
Crystal 0.36.1 [c3a3c1823] (2021-02-02)

LLVM: 10.0.0
Default target: x86_64-unknown-linux-gnu

What if you forget about hunspell and just create a plain object with finalize on a loop? I’m also on Mac.

No issue.