Agent Ruby: a case of born digital art preservation, by Jill Sterrett
Threequals - Case Equality in Ruby
-
Upload
louis-scoras -
Category
Software
-
view
167 -
download
0
description
Transcript of Threequals - Case Equality in Ruby
Threequals
Ruby's greatest operator===
Me
===
/Lou(?: Scoras)/ === nameemail === "[email protected]"codes === :"github.com/ljsc"
10..(1.0/0) === ruby.years_codingworks === "Econify.com"
Me
The equals sign
===
What does it mean in ruby?
The equals sign
It depends on how
The equals sign
loudly youYELL.
=(Whispered.)
==(Inside voice.)
===(IRC SHOUT!)
Case Equality
===
Case Equality
Use case equality whenever you need to discriminate between one or more cases.
Case Equality
This operator and the case statement go hand in hand.
Case Equality
x = gets.strip.to_i
case xwhen 1 then "one"when 2 then "two"when 3 then "three"end
Case Equality
x = gets.strip.to_i
case xwhen 1 then "one"when 2 then "two"when 3 then "three"end
if 1 === x "one"elsif 2 === x "two"elsif 3 === x "three"end
Case Equality
case x when 1 then "one"
if 1 === x
Case Equality
Case equality is not symmetric in general.
Case Equality
pattern target===
Case Equality
if 1 === x "easy"elsif 2 === x || 3 === x "struggling"else "Why do you make me work so hard?"end
case xwhen 1 then "easy"when 2, 3 "struggling"else "Why do you make me work so hard?"end
The Default
===
The Default
"For class Object, effectively the same as calling ==, but typically overridden by descendants to provide meaningful semantics in case statements."
Useful Builtins
===
Useful Builtins
Class Semantics Notes
Object ==
Regex match Returns a boolean
Range include?
Fixnum/Bignum/Float == Coerces numeric types
Class (Module) is_a? On an instance
Proc call
Predicate Objects
===
Predicate Objects
Predicates are functions that return a boolean value.
Predicate Objects
Create objects to encapsulate case equality operations.
Predicate Objects
What is your quest?
Predicate Objects
class Proceed def ===(knight) knight.favorite_color == "blue" endend
Predicate Objects
class Doomed def ===(knight) knight.knows_capital?("Assyria") endend
Predicate Objects
def cross_bridge!(knight) case knight when Doomed.new then "ARGGGH!!" when Proceed.new then "Right, off you go" endend
Parameterize!
===
Parameterize!
class LikesColor def initialize(color) @color = color end def ===(knight) knight.favorite_color == @color endend
Parameterize!
def cross_bridge!(knight) case knight when LikesColor.new("Yellow") "ARGGGH!!" when LikesColor.new("Blue") "Right, off you go" endend
Composites
===
Composite Pattern
"The composite pattern describes that a group of objects is to be treated in the same way as a single instance of an object."
http://en.wikipedia.org/wiki/Composite_pattern
Composite Pattern
UML (purposefully) omitted.
Composite Pattern
Composite Pattern
The "has-a" is not the important part!
Composite Pattern
The "has-a" is not the important part!
Not limited to things that are obviously trees.
Composite Pattern
The most important idea in programming (™): Closure
Composite Pattern
(Not the lexical kind)
The most important idea in programming (™): Closure
Closure Property
Closed operation: Takes one or more object of type T and returns something of type T.
f : Tn -> T
The BridgePt.2
===
The Bridge pt.2
class Or def initialize(a, b) @a, @b = a, b end def ===(other) @a === other || @b === other endend
The Bridge pt.2
class Or def initialize(a, b) @a, @b = a, b end def ===(other) @a === other || @b === other endend
The magic part
The Bridge Pt.2
def cross_bridge!(knight) case knight when Or.new(KnightNamed.new("Lancelot"), KnightNamed.new("Arthur") "Right, off you go" when WearingColor.new("Green") "Kind of arbitrary isn....ARGGGH!!" endend
What a Mouthful
===
What a Mouthful
What a Mouthful
This is all very nice, but it's kind of verbose.
What a Mouthful
This might be a good time for a very thin "DSL" layer.
What a Mouthful
module Threequals::DSL def _and(a,b); And.new(a,b) end def _or(a,b); Or.new(a,b) end def named(a); KnightNamed.new(a) end def doomed(a); Doomed.new(a) endend
The Bridge Pt.3
===
The Bridge Pt.3
def cross_bridge!(knight) extend Threequals::DSL case knight when _or(named("Lancelot"), named("Arthur")) "Right, off you go" when wears "Green" "Kind of arbitrary isn....ARGGGH!!" endend
On Duck Typing
===
On Duck Typing
Why does this work so well for ===?
On Duck Typing
Duck types work best when:
On Duck Typing
Duck types work best when:● The operation(s) are abstract.
On Duck Typing
Duck types work best when:● The operation(s) are abstract.● The interface is granular.
On Duck Typing
Ruby should code should steal this part of functional programming.
On Duck Typing
Ruby should code should steal this part of functional programming.
Not "Proc Soup".
Wrapping Up
===
Wrapping up
We should steal functional ideas, but make them idiomatic
Wrapping up
We should steal functional ideas, but make them idiomatic (we created a poormans pattern matching).
Wrapping up
We should steal functional ideas, but make them idiomatic (we created a poormans pattern matching).
Threequals/case is awesome. Use it.
Wrapping up
We should steal functional ideas, but make them idiomatic (we created a poormans pattern matching).
Threequals/case is awesome. Use it.
Composition is king!
Thanks!
===
Questions?
===
Image credits
"Loud" John Watson. https://flic.kr/p/UfVK"Bridge Climb" Alan. https://flic.kr/p/acyZPw"Compound of five small stellated dodecahedra"
fdecomite. https://flic.kr/p/9ZfhWf"peekaboo" ankakay. https://flic.kr/p/6TSAPW