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
150
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Virtus
Florian Gilcher
October 10, 2013
More Decks by Florian Gilcher
See All by Florian Gilcher
A new contract with users
skade
1
550
Using Rust to interface with my dive computer
skade
0
320
async/.await with async-std
skade
1
830
Training Rust
skade
1
150
Internet of Streams - IoT in Rust
skade
0
130
How DevRel is failing communities
skade
0
140
The power of the where clause
skade
0
720
Three Years of Rust
skade
1
250
Rust as a CLI language
skade
1
250
Other Decks in Programming
See All in Programming
AIの中の人になってみる
htkym
0
170
信頼性の目標を誰も求めてない
shubox
0
490
From 6 People Classroom Meetup to 100 People Regional Conference / FOSS4G Hiroshima 2026
furukawayasuto
0
120
ALB ログから Trace を気合で繋げる技術
fohte
7
880
AI Agent時代のリアーキテクチャ戦略と実践
hokaccha
0
180
思考垂れ流し開発 ~音声入力 × AIエージェント × 開発ハーネスによる試行錯誤~
npostring
0
930
kubernetes コンポーネント開発入門 / 新卒N年目の勉強会&交流会!〜〇〇への誘い〜 #n_study
mazrean
0
170
Building an Out-of-Order CPU
latte72
1
720
Webプラットフォームで議論されているセキュリティ課題 / Security issues being discussed on Web Platforms
petamoriken
0
210
AWS DevOps Agentで インシデント対応をAIに任せたい
honmarkhunt
7
2.5k
Go × SIMDで高速化するベクトル検索 ~ルーフラインモデルでSIMDが効く境界を探れ! ~
po3rin
1
160
自分的「カンファレンスの楽しみ方」
syumai
0
190
Featured
See All Featured
How to build a perfect <img>
jonoalderson
1
6k
From π to Pie charts
rasagy
0
360
SEO in 2025: How to Prepare for the Future of Search
ipullrank
3
3.8k
Taking LLMs out of the black box: A practical guide to human-in-the-loop distillation
inesmontani
PRO
3
2.4k
Redefining SEO in the New Era of Traffic Generation
szymonslowik
1
410
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
56
3.5k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
234
17k
Leveraging Curiosity to Care for An Aging Population
cassininazir
1
490
Chasing Engaging Ingredients in Design
codingconduct
0
300
Paper Plane (Part 1)
katiecoart
PRO
1
11k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
49
10k
AI in Enterprises - Java and Open Source to the Rescue
ivargrimstad
0
1.5k
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.