What happens to lingering Tuples?

Hi again! Sorry for all the questions lately, I’ve been on a roll!

Example code:
https://play.crystal-lang.org/#/r/64qu/edit

alias ItemTuple = Tuple(Int64, Int32, String, Int16, Int8, Int8, Float64, Float64, Float64, Float64, Int8)
class Item
  property i : ItemTuple
  property x = 0_f32
  property y = 0_f32
  def initialize(@x : Float32, @y : Float32, @i : ItemTuple)
  end
  
end

class Game
  property loot = Hash(Int64, Item).new
end

class GameServer
  property games = Hash(String, Game).new
end

gs = GameServer.new

# fill her up
10.times do |x|
  new_name = "game#{x}"
  gs.games[new_name] = Game.new
  gs.games[new_name].loot[x.to_i64] = Item.new(0.00f32, 0.00f32, {123_i64, 1, "", 12_i16, 0_i8, 0_i8, 0.00, 0.00, 0.00, 0.00, 0_i8})
end
puts gs.games.size
10.times do |x|
  gs.games.delete "game#{x}"
  # buh bye
end

puts gs.games.size

One might see this code and think hm… it’s working as intended. And that’s probably true. Except, if you take a closer look at what’s going on, you will notice the loot hash derived from the class Game doesn’t get deleted / cleared. However, the game instance itself is deleted.

My question is: What happens to those Item tuples that were created and stored under the instantiated game object (Game)? Does the GC handle them when it finds out there are no references to the tuples anymore? In this case and specific code, there are no other references to the tuple data, so it’s safe to say the GC will take care of it? If not, would I need to add

gs.games["game#{x}"].loot.clear

before

gs.games.delete "game#{x}"

?

Yes, they’re cleaned up by the GC.

2 Likes

Definitely more at ease now, thanks @RX14!