Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Speaker Deck
PRO
Sign in
Sign up
for free
Tokyo Ruby Kaigi
Aaron Patterson
May 28, 2016
Technology
5
2.4k
Tokyo Ruby Kaigi
My talk from Tokyo Ruby Kaigi
Aaron Patterson
May 28, 2016
Tweet
Share
More Decks by Aaron Patterson
See All by Aaron Patterson
tenderlove
52
3.4k
tenderlove
7
11k
tenderlove
1
210
tenderlove
2
180
tenderlove
16
2.1k
tenderlove
10
480
tenderlove
7
2.3k
tenderlove
4
600
tenderlove
4
240
Other Decks in Technology
See All in Technology
clustervr
0
160
sky_joker
0
110
opdavies
0
1.6k
humank
0
220
tdys13
5
3.5k
mmarukaw
0
1.5k
ocise
1
1.3k
natsusan
0
190
nihonbuson
2
1.9k
ocise
0
150
hhiroshell
7
460
greymd
0
630
Featured
See All Featured
lynnandtonic
271
16k
jasonvnalue
82
8.1k
jonyablonski
14
1.1k
trallard
13
640
cromwellryan
101
5.9k
eitanlees
111
9.9k
danielanewman
200
20k
sferik
609
54k
jponch
103
5k
tammielis
237
23k
kastner
54
1.9k
philnash
8
500
Transcript
None
͜Μʹͪʂ
ຊޠೖྗࢼݧ
Aaron Patterson @tenderlove
GitHub
ko1: ϓϩάϥϛϯάΛ͍ͯͯ͠ʮ͓͓ɺ ੌ͍ίʔυ͕ॻ͚ͨʯʮ͜Εੌ͍ͷ Λ࡞ͬͯ͠·ͬͨʯͷΑ͏ͳܦݧͳͲ
Me: ʮੌ͍ίʔυʯ ͍͍ͬͯͬͨԿͩΖ͏
None
;ͨͭͷҙຯ ڪΖ͍͠ / ා͍ ૉΒ͍͠ / ྑ͍
ೋͭͷτϐοΫ ڪΖ͍͠ / ා͍: PHP ૉΒ͍͠ / ྑ͍: Computer Vision
ൿີ
ੌ͍ίʔυ ૉΒ͍͠ / ྑ͍
ίϯϐϡʔλ Ϗδϣϯ
ΨϥΫλ͕ ͍ͬͺ͍
Magic The Gathering (MtG)ͱ
Collectible Card Game
ࢲͷ (Χʔυͷத) • Too many cards • Don’t know what
they do • Are they worth any money? • Plus many more!
ίϯϐϡʔλʔʹ߹͏ Έ͍ͨ Seems like a job for computers!
ࢲͷղܾ
ਓೳ Χϝϥ ೣ! Ruby!
High Level Process
ࣸਅΛࡱΔ ΧʔυΛൈ͚Δ ΧʔυΛ֬ೝ͢Δ σʔλΛอଘ͢Δ
Χʔυͷೝࣝ
श ͬͨ ਪଌ ϓϩϯϓτ ڭ͑Δ ίʔύε
श ͬͨ ਪଌ ϓϩϯϓτ ڭ͑Δ ίʔύ ε
ਓೳ
σʔλɹϞσϧ
Χʔυͷใ
ࣸਅ ໊લ ਓؾ ηοτ
image belongs_to(:card) card has_one(:image)
None
image belongs_to(:card) card has_many(:images)
None
image habtm(:cards) card habmt(:image)
શσʔλϞσϧ Cards Images Hashes habtm has_many
ίʔύεͷੜ
Executor Pool class ThreadExecutor def initialize size @queue = Queue.new
@size = size @pool = size.times.map { |i| Thread.new { while job = @queue.pop; job.run end } } end def execute job = Proc.new promise = Promise.new job @queue << promise promise end def shutdown @size.times { @queue << nil } @pool.each(&:join) end end
Queue up work promise = @executor.execute do @http_pool.with_connection do |conn|
uri = URI 'http://gatherer.wizards.com/Pages/Default.aspx' response = conn.request uri # save the response end end # some time later promise.value
Me Wizards
1.6GB
http://mtgjson.com/
ॻ͘લʹ άʔάϧͨ͠ํ͕͍͍
Χʔυͷೝࣝ
֮తϋογϡ libphash (gem install phasion)
11998341215223291070 12079686925145871551 Reference Scanned
ϋϛϯάڑ require 'phashion' left = Phashion.image_hash_for "a.jpg" right = Phashion.image_hash_for
"b.jpg" p Phashion.hamming_distance left, right # => 8
5622372658725034411 12079686925145871551 Reference Scanned
ϋϛϯάڑ require 'phashion' left = Phashion.image_hash_for "c.jpg" right = Phashion.image_hash_for
"b.jpg" p Phashion.hamming_distance left, right # => 28
ϋογϡΛՃ͢Δͱ ͕ࣝ૿͑Δ
ϋʔυΣΞ
None
None
None
ιϑτΣΞ
OpenCV https://github.com/ruby-opencv/ruby-opencv
ࡱͬͨࣸਅ
None
ཉ͍͠Πϝʔδ
None
Χʔυͷൈ͖ํ
؆୯ͳ8ஈ֊͚ͩ!* * ؆୯͡Όͳ͍ɺଟ
None
લॲཧ
άϨʔεέʔϧ gray = OpenCV.BGR2GRAY img
None
Τοδݕग़ canny_img = gray.canny @thresh, @thresh http://en.wikipedia.org/wiki/Canny_edge_detector
None
ྠֲΛݟ͚ͭΔ contours = [] contour_node = processed.find_contours( :mode => OpenCV::CV_RETR_TREE,
:method => OpenCV::CV_CHAIN_APPROX_SIMPLE) while contour_node unless contour_node.hole? contours << contour_node end contour_node = contour_node.h_next end
ྠֲ ݀
None
Ұ൪େ͖ͳྠֲ max = contours.max_by { |c| c.contour_area }
None
ଟ֯ܗΛݟ͚ͭΔ approx = max.approx_poly(:method => :dp, :recursive => true, :accuracy
=> 0.02 * peri) x = approx.convex_hull2.to_a clockwise_points = clockwise x.reverse
None
ಁࢹมͷߦྻ to = [ OpenCV::CvPoint2D32f.new(0, 0), OpenCV::CvPoint2D32f.new(width, 0), OpenCV::CvPoint2D32f.new(width, height),
OpenCV::CvPoint2D32f.new(0, height), ] from = polygon_points transform = OpenCV::CvMat.get_perspective_transform(from, to)
ΠϝʔδΛม͢Δ new_img = img.warp_perspective transform
None
ڥք࠲ඪΛઃఆ͢Δ new_img.set_roi OpenCV::CvRect.new(0, 0, width, height)
None
It’s Just That Easy!
ϢʔβʔΠϯλʔϑΣΠε ΧϝϥͰ ࡱͬͨ Πϝʔδ ਪଌ #1 ਪଌ #2 ਪଌ #3
None
Կ͕͋Δʁ Card.joins(:images) .where('images.type' => 'UserImage') .group('cards.name') .count
Ͳͷ͙Β͍ྑ͍ʁ Card.joins(:images) # best .where('images.type' => 'UserImage') .order('rating desc').first Card.joins(:images)
# worst .where('images.type' => 'UserImage') .order('rating asc').first
࠷ߴ:
࠷:
ϓϩδΣΫτͷ
যͷ࣌ؒ
None
ࣦഊͷ࣌
None
ֆࣅͯΔ
None
अຐೣ
None
ར ઃఆ؆୯ ඞཁϋʔυΣΞ͋·Γͳ͍ ͍҆ ΩϟϦϒϨʔτ͠ͳ͍
ܽ ෳࡶͳιϑτΣΞ ࿑ಇ ֬ೝͷ͞
ࠓޙͷ׆ಈ
ࣗಈԽ
ੌ͍ίʔυ ڪΖ͍͠ / ා͍
PHP + Ruby
Phuby (ϑʔϏΟ) https://github.com/tenderlove/phuby એ
Examples
PHPͷ ΦϒδΣΫτΛ͏
ࣈ require 'phuby' Phuby::Runtime.php do |runtime| runtime.eval "$v = strlen('PHP
INSIDE OF RUBY');" puts runtime['v'] # => 18 end
จࣈྻ require 'phuby' Phuby::Runtime.php do |runtime| runtime.eval "$name = 'Aaron';"
puts runtime['name'] # => Aaron end
ྻ require 'phuby' Phuby::Runtime.php do |runtime| runtime.eval "$cars = array('Toyota',
'Honda', 'BMW');" p runtime['cars'][0] # => Toyota p runtime['cars'][1] # => Honda p runtime['cars'][2] # => BMW end
࿈ྻ require 'phuby' Phuby::Runtime.php do |runtime| runtime.eval "$e = array('foo'
=> 'bar', 'bar' => 'baz');" p runtime['e']['foo'] # => 'bar' p runtime['e']['bar'] # => 'baz' end
Rubyͷ ΦϒδΣΫτΛ͏
Objects require 'phuby' class RubyKaigi def where puts "౦ژ" end
end Phuby::Runtime.php do |runtime| runtime['kaigi'] = RubyKaigi.new runtime.eval("$kaigi->where();") # => ౦ژ end
ͳͥʁ
͍͍͔Β
scientists were so preoccupied with whether or not they could
that they didn't stop to think if they should.
ϓϩάϥϜͷମܕ
Runtime Proxy Object Map Ruby Object Proxy PHP Object Proxy
Wrapper Access PHP Objects Ruby C PHP Object Map Ruby
Proxy PHP Runtime Object
Wrapper Access Ruby Objects Ruby C PHP Object Map Ruby
Proxy PHP Runtime Object
ϓϩδΣΫτͷ
PHPΛ ίϯύΠϧ͢Δ
GC
άϩʔόϧͷม
require 'phuby' require 'openssl' p OpenSSL::Cipher.ciphers # => ["AES-128-CBC",
"AES-128-CBC-HMAC-SHA1", ... ] Phuby::Runtime.php do |runtime| runtime.eval("$hi = 'Hello World';") end p OpenSSL::Cipher.ciphers # => []
Solution: fork require 'phuby' require 'openssl' p OpenSSL::Cipher.ciphers # =>
["AES-128-CBC", "AES-128-CBC-HMAC-SHA1", ... ] Process.waitpid fork { Phuby::Runtime.php do |runtime| runtime.eval("$hi = 'Hello World';") end } p OpenSSL::Cipher.ciphers # => ["AES-128-CBC", "AES-128-CBC-HMAC-SHA1", ... ]
Rails Support
PHP templates
None
Πϯελϯεม
None
ActiveRecord͑·͢
None
How much would you pay for this?
200ԁ?
250ԁ?
https://github.com/ tenderlove/phuby FREE!
ൿີͷτϐοΫ
ko1 said this is a tech conference, so you don’t
have to tell any jokes
So I won’t tell any jokes.
ੌ͍ίʔυ How does it work?
Homeopathic Optimizations
Homeopathy ͱʁ
رऍɻ
͗͢Δʂ
None
None
Modern advocates of homeopathy have proposed a concept of "water
memory", according to which water "remembers" the substances mixed in
ਫ هԱग़དྷ·͢
ۭന هԱ͢Δࣄ͕Ͱ͖Δʁ
YES!
σϞͷ࣌ؒ!
None
Ͳ͏ͬͯ ಈ͍ͯΔʁ
VM هԱ͢Δ
ͦΕۭന͡Όͳ ͯ͘ɺهԱͩɻ
ଞͷಛ
None
ར
ߴԽ
"No code is faster than no code"
رऍ͞ΕΕ͞ΕΔ΄Ͳ ϓϩάϥϜΑΓ͘ͳ Δ
ҡ࣋
ίʔυͳ͍͔Β
THANK YOU!!!
࣭ʁ