Part of DataMapper 2 Is Done - Announcing Virtus 0.5.0
UPDATE: DataMapper 2 was renamed to Ruby Object Mapper (ROM). For more info check out rom-rb.org
I’m happy to announce that Virtus 0.5.0 was released. It’s sort of a milestone for me as Virtus is now considered feature-complete and I’m quite happy with the code. Further development will only focus on bug fixes and small internal clean ups. We plan to extract smaller pieces into separate gems at some point too. Specifically Coercion mechanism, DescendantsTracker and Equalizer will very likely become separate gems.
So, what’s new in 0.5.0?
Using Virtus in Modules
The release brings support for using Virtus within modules. The feature was requested some time ago but I postponed the implementation until there was a bigger demand. I was a bit worried that supporting this will complicate the code too much but it turned out I was wrong :)
Using Virtus in modules is as easy as this:
module Publishable
include Virtus
attribute :title, String
attribute :author, String
attribute :publish_on, Date
end
class Article
include Publishable
end
class Book
include Publishable
end
book = Book.new(
title: "Foo Bar", author: "John Doe", publish_on: Date.today)
article = Article.new(
title: "Review of Foo Bar", author: "Jane Doe", publish_on: Date.today)
Thanks to this feature Representable gem, which now uses Virtus for coercions, can be used in both classes and modules. So enjoy it!
Extending Objects “on the fly”
It is also possible now to dynamically extend objects and define attributes on them. Check this out:
class Book
end
book = Book.new
book.extend(Virtus).attribute(:title, String)
book.title = "DCI with Virtus for fun and profit"
book.title
# => "DCI with Virtus for fun and profit"
book.attributes = { title: "DCI with Virtus for fun and profit ver. 2.0" }
book.title
# => "DCI with Virtus for fun and profit ver. 2.0"
Improved Embedded Value with support for Struct
That’s a small but beautiful addition - you can now use a Struct as an Embedded Value attribute type. Here’s a short example showing what I mean:
Point = Struct.new(:x, :y)
class Rectangle
include Virtus
attribute :top_left, Point
attribute :bottom_right, Point
end
rectangle = Rectangle.new(:top_left => [ 3, 5 ], :bottom_right => [ 8, 7 ])
rectangle.top_left.x # => 3
rectangle.top_left.y # => 5
rectangle.bottom_right.x # => 8
rectangle.bottom_right.y # => 7
You are not forced to use structs of course. You can use a custom class with a custom initialize method and it’s still going to work.
What’s Next?
Virtus is one of the pieces of DataMapper 2, since it’s mostly done we can safely say that a significant part of DM2 is done too. I’m switching my focus to dm-mapper now so expect more work there in the upcoming weeks.
If you haven’t done it yet - I encourage you to try out Virtus and tell me what you think. We want it to be rock solid for DataMapper 2 release!