How to enforce immutability to prevent the modification of values in Ruby

1 Answer

0 votes
# Immutable User in Ruby (Using freeze and Read-Only Attributes)

#
# Ruby does NOT enforce immutability by default,
# but you can strongly enforce it using:
#
# 1. freeze → prevents modification of the object
# 2. attr_reader → read-only access to fields
# 3. no setters → no mutation path
# 4. freezing nested values → deep immutability
#
# Attempting to modify a frozen object raises:
#   FrozenError: can't modify frozen object
#

class User
  # Read-only attributes
  attr_reader :id, :name

  def initialize(id, name)
    @id = id.freeze      # freeze internal values
    @name = name.freeze
    freeze               # freeze the entire object
  end
end

# Create an immutable user
user = User.new(42, "Sophia")

puts "ID: #{user.id}"
puts "Name: #{user.name}"

# Attempt 1: modify id
begin
  user.id = 100   # undefined method 'id=' for an instance of User
rescue => e
  puts "Blocked: #{e.message}"
end

# Attempt 2: modify name
begin
  user.name.replace("Tim")  # can't modify frozen String: "Sophia"
rescue => e
  puts "Blocked: #{e.message}"
end

# Attempt 3: modify instance variable directly
begin
  user.instance_variable_set(:@id, 100)  # can't modify frozen User
rescue => e
  puts "Blocked: #{e.message}"
end

# Attempt 4: modify object after freeze
begin
  user.instance_eval { @name = "Tim" }   # can't modify frozen User
rescue => e
  puts "Blocked: #{e.message}"
end

# Demonstrate safe reading
id_copy = user.id
name_copy = user.name

puts "ID copy: #{id_copy}"
puts "Name copy: #{name_copy}"


=begin
/* run:

ID: 42
Name: Sophia
Blocked: undefined method 'id=' for an instance of User
Blocked: can't modify frozen String: "Sophia"
Blocked: can't modify frozen User: #<User:0x0000793c97d73190 @id=42, @name="Sophia">
Blocked: can't modify frozen User: #<User:0x0000793c97d73190 @id=42, @name="Sophia">
ID copy: 42
Name copy: Sophia

*/
=end

 



answered 4 hours ago by avibootz
...