Ruby Data Objects
Data.define builds a small value class with named fields. Its objects are frozen from the start, so a change makes a new object.
Building a frozen point
The Point class comes from Data.define with the fields x and y. The new object answers its reader and reports frozen? as true.
Point = Data.define(:x, :y)
point = Point.new(x: 3, y: 4)
puts point.x
puts point.frozen?Changing a copy with with
with builds a new point with x changed to 10 and y carried over. The first point still reads x as 3.
Point = Data.define(:x, :y)
point = Point.new(x: 3, y: 4)
changed = point.with(x: 10)
puts changed.x
puts changed.y
puts point.xComparing data objects by value
Two points with the same field values compare as equal. A point with a different x value does not.
Point = Data.define(:x, :y)
first = Point.new(x: 3, y: 4)
second = Point.new(x: 3, y: 4)
third = Point.new(x: 5, y: 4)
puts first == second
puts first == thirdReading members and values
members lists the field names as symbols. to_h pairs each name with the value the object holds.
Point = Data.define(:x, :y)
point = Point.new(x: 3, y: 4)
p Point.members
p point.to_hExample
City = Data.define(:name, :population)
city = City.new(name: "Oslo", population: 700)
moved = city.with(population: 710)
puts moved.population
puts city.population
puts moved.frozen?Key points
- Data.define takes field names and returns a new class.
- An instance reports frozen? as true.
- with builds a new object with some fields changed.
- The original object keeps its old values after with.
- Two data objects are == when their fields hold equal values.
- to_h builds a hash from the field names and values.
- members lists the field names in order.
In this example, City is a data class with name and population fields. with builds a second city with population 710 while the first city keeps 700. The last line confirms that the new object is frozen too.
Try it Yourself
Edit the code, then press Run.
Running is simulated
Exercise
A data object holds x as 3. What does with(x: 9) do to that object itself?