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
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
Florian Gilcher
October 10, 2013
Programming
0
150
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
520
Using Rust to interface with my dive computer
skade
0
290
async/.await with async-std
skade
1
800
Training Rust
skade
1
140
Internet of Streams - IoT in Rust
skade
0
120
How DevRel is failing communities
skade
0
120
The power of the where clause
skade
0
680
Three Years of Rust
skade
1
220
Rust as a CLI language
skade
1
230
Other Decks in Programming
See All in Programming
AI Assistants for Your Angular Solutions
manfredsteyer
PRO
0
140
Goの型安全性で実現する複数プロダクトの権限管理
ishikawa_pro
2
310
DSPy入門 Pythonで実現する自動プロンプト最適化 〜人手によるプロンプト調整からの卒業〜
seaturt1e
1
710
エージェント開発初心者の僕がエージェントを作った話と今後やりたいこと
thasu0123
0
240
go directiveを最新にしすぎないで欲しい話──あるいは、Go 1.26からgo mod initで作られるgo directiveの値が変わる話 / Go 1.26 リリースパーティ
arthur1
2
550
Understanding Apache Lucene - More than just full-text search
spinscale
0
110
maplibre-gl-layers - 地図に移動体たくさん表示したい
kekyo
PRO
0
260
AIに任せる範囲を安全に広げるためにやっていること
fukucheee
0
130
Claude Codeログ基盤の構築
giginet
PRO
7
3.1k
AWS Infrastructure as Code の新機能 2025 総まとめ 〜SA 4人による怒涛のデモ祭り〜
konokenj
10
3.3k
Agentic AI: Evolution oder Revolution
mobilelarson
PRO
0
160
守る「だけ」の優しいEMを抜けて、 事業とチームを両方見る視点を身につけた話
maroon8021
3
830
Featured
See All Featured
Intergalactic Javascript Robots from Outer Space
tanoku
273
27k
Groundhog Day: Seeking Process in Gaming for Health
codingconduct
0
120
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
Exploring anti-patterns in Rails
aemeredith
2
290
Hiding What from Whom? A Critical Review of the History of Programming languages for Music
tomoyanonymous
2
540
The Spectacular Lies of Maps
axbom
PRO
1
620
The SEO Collaboration Effect
kristinabergwall1
0
390
Optimising Largest Contentful Paint
csswizardry
37
3.6k
The Organizational Zoo: Understanding Human Behavior Agility Through Metaphoric Constructive Conversations (based on the works of Arthur Shelley, Ph.D)
kimpetersen
PRO
0
270
Mind Mapping
helmedeiros
PRO
1
120
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
12
1.1k
GraphQLとの向き合い方2022年版
quramy
50
14k
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.