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
450
Using Rust to interface with my dive computer
skade
0
200
async/.await with async-std
skade
1
730
Training Rust
skade
1
80
Internet of Streams - IoT in Rust
skade
0
71
How DevRel is failing communities
skade
0
60
The power of the where clause
skade
0
570
Three Years of Rust
skade
1
160
Rust as a CLI language
skade
1
180
Other Decks in Programming
See All in Programming
変化の激しい時代における、こだわりのないエンジニアの強さ
satoshi256kbyte
1
130
CSS Linter による Baseline サポートの仕組み
ryo_manba
1
160
Datadog Workflow Automation で圧倒的価値提供
showwin
1
320
CloudNativePGを布教したい
nnaka2992
0
120
.NET Frameworkでも汎用ホストが使いたい!
tomokusaba
0
210
やっと腹落ち「スプリント毎に動くモノをリリースする」〜ゼロから始めるメガバンクグループのアジャイル実践〜
sasakendayo
0
190
Your Architecture as a Crime Scene:Forensic Analysis @bastacon 2025 in Frankfurt
manfredsteyer
PRO
0
110
Go 1.24でジェネリックになった型エイリアスの紹介
syumai
2
310
AIプログラミング雑キャッチアップ
yuheinakasaka
20
5.3k
GoとPHPのインターフェイスの違い
shimabox
2
220
PHPカンファレンス名古屋2025 タスク分解の試行錯誤〜レビュー負荷を下げるために〜
soichi
1
760
推しメソッドsource_locationのしくみを探る - はじめてRubyのコードを読んでみた
nobu09
2
360
Featured
See All Featured
Fireside Chat
paigeccino
35
3.2k
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
49
2.3k
Building Your Own Lightsaber
phodgson
104
6.2k
Embracing the Ebb and Flow
colly
84
4.6k
Learning to Love Humans: Emotional Interface Design
aarron
273
40k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
6
580
Fantastic passwords and where to find them - at NoRuKo
philnash
51
3k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
100
18k
What's in a price? How to price your products and services
michaelherold
244
12k
The Art of Programming - Codeland 2020
erikaheidi
53
13k
Raft: Consensus for Rubyists
vanstee
137
6.8k
Making Projects Easy
brettharned
116
6k
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.