Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Virtus
Search
Florian Gilcher
October 10, 2013
Programming
0
140
Virtus
Florian Gilcher
October 10, 2013
Tweet
Share
More Decks by Florian Gilcher
See All by Florian Gilcher
A new contract with users
skade
1
490
Using Rust to interface with my dive computer
skade
0
240
async/.await with async-std
skade
1
780
Training Rust
skade
1
100
Internet of Streams - IoT in Rust
skade
0
89
How DevRel is failing communities
skade
0
80
The power of the where clause
skade
0
630
Three Years of Rust
skade
1
180
Rust as a CLI language
skade
1
210
Other Decks in Programming
See All in Programming
開発チーム・開発組織の設計改善スキルの向上
masuda220
PRO
20
11k
Putting The Genie in the Bottle - A Crash Course on running LLMs on Android
iurysza
0
140
実用的なGOCACHEPROG実装をするために / golang.tokyo #40
mazrean
1
270
Introducing ReActionView: A new ActionView-compatible ERB Engine @ Rails World 2025, Amsterdam
marcoroth
0
680
testingを眺める
matumoto
1
140
1から理解するWeb Push
dora1998
7
1.9k
Compose Multiplatform × AI で作る、次世代アプリ開発支援ツールの設計と実装
thagikura
0
150
Performance for Conversion! 分散トレーシングでボトルネックを 特定せよ
inetand
0
140
今から始めるClaude Code入門〜AIコーディングエージェントの歴史と導入〜
nokomoro3
0
130
AIと私たちの学習の変化を考える - Claude Codeの学習モードを例に
azukiazusa1
10
3.9k
JSONataを使ってみよう Step Functionsが楽しくなる実践テクニック #devio2025
dafujii
1
530
Ruby×iOSアプリ開発 ~共に歩んだエコシステムの物語~
temoki
0
270
Featured
See All Featured
Building Applications with DynamoDB
mza
96
6.6k
We Have a Design System, Now What?
morganepeng
53
7.8k
Optimising Largest Contentful Paint
csswizardry
37
3.4k
[RailsConf 2023] Rails as a piece of cake
palkan
57
5.8k
Fashionably flexible responsive web design (full day workshop)
malarkey
407
66k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
656
61k
How To Stay Up To Date on Web Technology
chriscoyier
790
250k
The Invisible Side of Design
smashingmag
301
51k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
26
3k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
9
810
Embracing the Ebb and Flow
colly
87
4.8k
How STYLIGHT went responsive
nonsquared
100
5.8k
Transcript
News!!!
Rails Rumble 2013 http://railsrumble.com/ Signup ends Oct. 13th
http://gotocon.com/berlin-2013/
URM
Unsung Rubyist of the Month
http://www.ruby-mine.de/wonado http://www.ruby-mine.de/regexp
Virtus
DataMapper: The Awesome Parts
This is a partial extraction of the DataMapper Property API
with various modifications and im- provements. The goal is to provide a common API for defining attributes on a model...
The README covers (almost) all, so I am not iterating
through the examples.
class User include Virtus.model attribute :name, String attribute :age, Integer
attribute :birthday, Date attribute :registered, Time, :default =>->() { Time.now } end
json = '{"name": "Florian Gilcher", "age": 30, "birthday": "October 4th,
1983"}' parsed = JSON.parse(json) user = User.new(parsed) #=> #<User:0x000001008d8b68 @age=30, @birthday= #<DateTime: 1983-10-04T...>, @name="Florian Gilcher", @registered="....">
module Named include Virtus.module attribute :name, String end class User
include Named end u = User.new u.attributes = {:name => "Florian Gilcher"}
class Location include Virtus.value_object values do attribute :lat, BigDecimal attribute
:lon, BigDecimal end end Location.new(:lat => 1, :lon => 1) == Location.new(:lat => 1, :lon => 1)
All this actually consisted of 3 parts: • coercion •
constructor • mass assignment
class User include Virtus.model( :constructor => false, :mass_assignment => false
) attribute :name, String attribute :age, Integer attribute :birthday, DateTime end
class User include Virtus.model(:coerce => false) attribute :name, String attribute
:age, Integer attribute :birthday, DateTime end u = User.new u.age = "123" u.age #=> "123"
class Named include Virtus.module(:coerce => false) attribute :name, String end
class ShowOff attribute :users, Set[User] attribute :tags, Array[String] attribute :meta,
Hash[Symbol => String], :coerce => false attribute :i_dont_know_what_this_is_good_for, Hash[String => Hash[String => User]] end
What is this good for?
Object graph prototyping
ActiveRecord::serialize
class User < ActiveRecord::Base serialize :preferences end User.new(:name => "fgilcher",
:preferences => { :columns => 3, :scheme => "dark"} })
class User < ActiveRecord::Base serialize :preferences end User.new(:name => "fgilcher",
:preferences => { :columns => 3, :scheme => "dark"} })
class Preferences include Virtus.model attribute :columns, Fixnum, :default => 2
attribute :scheme, String end class User < ActiveRecord::Base serialize :preferences, Preferences end
pref = Preferences.new(:columns => 2, :scheme => "dark") User.create(:name =>
"fgilcher", :preferences => pref) User.first #=> #<User id: 1, name: "fgilcher", preferences: #<Preferences...>>
Or any other store storing complex values (NoSQL)
Form objects
require 'active_model' class Preferences include ActiveModel::Validations validates_presence_of :columns, :scheme end
Consider using Virtus every time you would use OpenStruct or
Hash in anger!
Handling attributes
att = Preferences.attribute_set[:columns] att.name #=> :columns att.coerce("2") #=> 2 att.default_value.value
#=> 2
hash.each do |k,v| setter_name = "#{k}=" object.send(setter_name, v) end
att.get(pref) #=> 2 att.set(pref, 3) #=> 3
Finally, a proper attribute setting API on all objects!
Final words
Virtus comes at a small cost, so it should be
used for domain models only.
This cost does JIT away very well in most cases.
Virtus shines through what it doesn’t do, not through what
it does.