Confusion about .dup with property macro


#1

check out the following code: https://play.crystal-lang.org/#/r/628n

DEFAULT_CHAR_IMG_ARRAY = [0, 0, 0, 0, 0, 0, 0, 0, 0]
CHAR_IMG               = {Weapons: 0, Weapon2: 1, Helmet: 2, Armor: 3, Gloves: 4, Boots: 5, Ring1: 6, Ring2: 7, Amulet: 8}


class Player
  # Works:
  # property char_img : Array(Int32) = DEFAULT_CHAR_IMG_ARRAY.dup
  # Doesn't work, why?
  # https://crystal-lang.org/api/0.23.1/Array.html#dup-instance-method
  # Says it RETURNS THE ARRAY!
  # so it should return [0, 0, 0, 0, 0, 0, 0, 0, 0]
  # thus, it becomes property char_img = [0, 0, 0, 0, 0, 0, 0, 0, 0] which does work
  property char_img = DEFAULT_CHAR_IMG_ARRAY.dup
  
end

def modify_char_img(player, type, v)
  player.char_img[CHAR_IMG[type]] = v
end


p = Player.new
modify_char_img(p, "Helmet", 1)


p1 = Player.new

puts p.char_img
puts p1.char_img

what’s the difference between:

property char_img : Array(Int32) = DEFAULT_CHAR_IMG_ARRAY.dup

and

property char_img = DEFAULT_CHAR_IMG_ARRAY.dup

because if you do

property char_img = [0, 0, 0, 0, 0, 0, 0, 0, 0]

it works fine?

After looking at the docs for Array’s #dup method, it says

Returns a new Array that has exactly self 's elements. That is, it returns a shallow copy of self .

If it’s returning an array, that means it’s returning [0, 0, 0, 0, 0, 0, 0, 0, 0].

Which is essentially:

property char_img = [0, 0, 0, 0, 0, 0, 0, 0, 0]

which is valid crystal code?


#2

The compiler only infers the type of instance and class variables from basic expressions, and never from instance method. Please check this docs entry.