GAURAV VARMA
Ruby 3.2 introduces a new core class called Data
, a lightweight way to define immutable value objects with less boilerplate. It’s ideal for modeling plain data structures where mutability isn’t needed and immutability is a benefit.
This addition helps Ruby stay competitive with modern language features, offering similar benefits to Struct
, but with stricter immutability and improved pattern matching compatibility.
What is the Data
class?
The Data
class is a subclass of Object
that behaves much like Struct
, but with immutable attributes and value equality out of the box.
Here’s how to define and use it:
1Person = Data.define(:name, :age)
2
3john = Person.new("John", 30)
4
5john.name
6# => "John"
7
8john.age
9# => 30
Unlike Struct
, trying to change john.name
will raise an error:
1john.name = "Mike"
2# => NoMethodError (undefined method `name=')
Why use Data
over Struct
?
1| Feature | Struct | Data |
2| ------------------------- | ----------------- | -------------------------- |
3| Mutable | ✅ Yes | ❌ No (immutable) |
4| Value-based equality | ✅ Yes | ✅ Yes |
5| Built-in pattern matching | ⚠️ Limited | ✅ Fully supported |
6| Safer for modeling | ❌ Prone to bugs | ✅ Encourages immutability |
If you don’t want your object’s state to change after initialization, Data
is the better choice. This is especially useful when you’re working with domain models, value objects, or functional-style programming.
Pattern Matching Support
The Data
class is optimized for pattern matching, a feature introduced in Ruby 2.7 and improved in later versions.
1case john
2in Person(name:, age:)
3 puts "Name: #{name}, Age: #{age}"
4end
5# => Name: John, Age: 30
Pattern matching works seamlessly and makes destructuring data objects intuitive.
Real-world Use Cases
- Value objects in DDD (Domain-Driven Design)
- Lightweight DTOs (Data Transfer Objects)
- Parameters passed across service layers
- Declarative and functional code styles
Notes
- The
Data
class is immutable and does not support custom instance methods by default. - You can still add methods via class reopening:
1Person = Data.define(:name, :age)
2
3class Person
4 def greeting
5 "Hello, #{name}!"
6 end
7end
8
9john.greeting
10# => "Hello, John!"
Resources
Summary
Ruby’s new Data
class is a welcome addition for developers who want clean, immutable, and efficient value objects with minimal syntax. It simplifies functional programming and domain modeling in Ruby, and its native support for pattern matching makes it a powerful new primitive in the language.