Ruby's Struct class is a great way to define simple classes. For example, to define a simple Point class with getter and setter methods for x and y attributes, along with working ==, hash, and to_s methods, we can just write:
Point = Struct.new(:x,:y)
Struct was designed with mutable types in mind, but that doesn't mean that we are restricted to mutable types. Here's how we change the just-defined Point class to be immutable:
Point = Struct.new(:x, :y) # Define mutable class class Point # Open the class undef x=,y=,[]= # Undefine mutator methods end
Why do this for all of your Struct-based classes, however? Let's add a new factory method to Struct itself. If you want an immutable structure, use Struct.immutable instead of Struct.new:
def Struct.immutable(*args) # Factory method for immutable classes
Struct.new(*args).class_eval do # Define struct, then modify it
undef []= # Undefine general mutator
args.each do |sym| # For each field of the struct
mutator = :"#{sym.to_s}=" # Symbol for setter method
remove_method mutator # Undefine that method
end
self # Return the class
end
end
Warning: I haven't actually tested this carefully, but it seems to work. Suggestions, corrections, etc., are welcome in the comments.



