Mutable và Immutable trong Ruby: object identity, mutation và allocation

Variable trong Ruby tham chiếu tới object. Assignment đổi reference; mutation đổi chính object.

1
2
3
4
5
name = "Hudson"
alias_name = name

name << " Tran"
alias_name # => "Hudson Tran"

String mutable nên hai variable cùng thấy thay đổi.

Rebinding không phải mutation

1
2
3
4
5
name = "Hudson"
alias_name = name

name = name + " Tran"
alias_name # => "Hudson"

+ tạo string mới rồi rebind name. Object cũ vẫn được alias_name giữ.

Kiểm tra identity:

1
2
name.object_id
name.equal?(alias_name)

Object thường immutable trong thực hành

Integer, symbol, nil, true, false không mutate theo cách String/Array/Hash làm:

1
2
number = 1
number += 1 # tạo/rebind integer khác

freeze ngăn mutation trực tiếp:

1
2
config = { timeout: 5 }.freeze
config[:timeout] = 10 # FrozenError

Nhưng freeze là shallow:

1
2
config = { headers: {} }.freeze
config[:headers][:token] = "x" # vẫn mutate nested hash

Muốn deep immutability cần freeze recursively hoặc dùng data structure/API phù hợp.

Bang method không phải luật mutation tuyệt đối

Nhiều bang method mutate receiver:

1
name.upcase!

Nhưng convention ! thường nghĩa “phiên bản nguy hiểm hơn so với method cùng tên”, không phải mọi method mutate đều có !. Ví dụ Array#push vẫn mutate.

Performance

Mutation có thể giảm allocation, nhưng shared mutable state tăng coupling, race condition và bug khó đoán. Immutable update thường dễ reason hơn nhưng có thể tạo object mới.

Đừng kết luận “Ruby ăn RAM vì string immutable/mutable” bằng vài object_id. Memory còn phụ thuộc allocator, GC, retained objects, copy-on-write và workload. Benchmark bằng tool như memory_profiler, stackprof, heap dump—không benchmark bằng cảm xúc khi laptop bật quạt.

Kết luận

Khi truyền object qua nhiều layer, hãy làm rõ ownership:

  • method có mutate argument không;
  • caller có giữ reference khác không;
  • có cần dup, immutable value object hoặc defensive copy không.

Bug mutable state hiếm khi nằm ở cú pháp. Nó nằm ở hai nơi cùng tin rằng object thuộc về mình.