Tokyo Ruby Kaigi

Tokyo Ruby Kaigi

My talk from Tokyo Ruby Kaigi

F29327647a9cff5c69618bae420792ea?s=128

Aaron Patterson

May 28, 2016
Tweet

Transcript

  1. None
  2. ͜Μʹͪ͸ʂ

  3. ೔ຊޠೖྗࢼݧ

  4. Aaron Patterson @tenderlove

  5. GitHub

  6. ko1: ϓϩάϥϛϯάΛ͍ͯͯ͠ʮ͓͓ɺ ੌ͍ίʔυ͕ॻ͚ͨʯʮ͜Ε͸ੌ͍΋ͷ Λ࡞ͬͯ͠·ͬͨʯͷΑ͏ͳܦݧͳͲ

  7. Me: ʮੌ͍ίʔυʯ ͍͍ͬͯͬͨԿͩΖ͏

  8. None
  9. ;ͨͭͷҙຯ ڪΖ͍͠ / ා͍ ૉ੖Β͍͠ / ྑ͍

  10. ೋͭͷτϐοΫ ڪΖ͍͠ / ා͍: PHP ૉ੖Β͍͠ / ྑ͍: Computer Vision

    ൿີ
  11. ੌ͍ίʔυ ૉ੖Β͍͠ / ྑ͍

  12. ίϯϐϡʔλ Ϗδϣϯ

  13. ΨϥΫλ͕ ͍ͬͺ͍

  14. Magic The Gathering (MtG)ͱ͸

  15. Collectible Card Game

  16. ࢲͷ໰୊ (Χʔυͷத਎) • Too many cards • Don’t know what

    they do • Are they worth any money? • Plus many more!
  17. ίϯϐϡʔλʔʹ߹͏ ໰୊Έ͍ͨ Seems like a job for computers!

  18. ࢲͷղܾ

  19. ਓ޻஌ೳ Χϝϥ ೣ! Ruby!

  20. High Level Process

  21. ࣸਅΛࡱΔ ΧʔυΛൈ͚Δ ΧʔυΛ֬ೝ͢Δ σʔλΛอଘ͢Δ

  22. Χʔυͷೝࣝ

  23. श ͬͨ ਪଌ ϓϩϯϓτ ڭ͑Δ ίʔύε

  24. श ͬͨ ਪଌ ϓϩϯϓτ ڭ͑Δ ίʔύ ε

  25. ਓ޻஌ೳ

  26. σʔλɹϞσϧ

  27. Χʔυͷ৘ใ

  28. ࣸਅ ໊લ ਓؾ౓ ηοτ

  29. image belongs_to(:card) card has_one(:image)

  30. None
  31. image belongs_to(:card) card has_many(:images)

  32. None
  33. image habtm(:cards) card habmt(:image)

  34. ׬શσʔλϞσϧ Cards Images Hashes habtm has_many

  35. ίʔύεͷੜ੒

  36. 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
  37. 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
  38. Me Wizards

  39. 1.6GB

  40. http://mtgjson.com/

  41. ॻ͘લʹ άʔάϧͨ͠ํ͕͍͍

  42. Χʔυͷೝࣝ

  43. ஌֮తϋογϡ libphash (gem install phasion)

  44. 11998341215223291070 12079686925145871551 Reference Scanned

  45. ϋϛϯάڑ཭ require 'phashion' left = Phashion.image_hash_for "a.jpg" right = Phashion.image_hash_for

    "b.jpg" p Phashion.hamming_distance left, right # => 8
  46. 5622372658725034411 12079686925145871551 Reference Scanned

  47. ϋϛϯάڑ཭ require 'phashion' left = Phashion.image_hash_for "c.jpg" right = Phashion.image_hash_for

    "b.jpg" p Phashion.hamming_distance left, right # => 28
  48. ϋογϡΛ௥Ճ͢Δͱ ஌͕ࣝ૿͑Δ

  49. ϋʔυ΢ΣΞ

  50. None
  51. None
  52. None
  53. ιϑτ΢ΣΞ

  54. OpenCV https://github.com/ruby-opencv/ruby-opencv

  55. ࡱͬͨࣸਅ

  56. None
  57. ཉ͍͠Πϝʔδ

  58. None
  59. Χʔυͷൈ͖ํ

  60. ؆୯ͳ8ஈ֊͚ͩ!* * ؆୯͡Όͳ͍ɺଟ෼

  61. None
  62. લॲཧ

  63. άϨʔεέʔϧ gray = OpenCV.BGR2GRAY img

  64. None
  65. Τοδݕग़ canny_img = gray.canny @thresh, @thresh http://en.wikipedia.org/wiki/Canny_edge_detector

  66. None
  67. ྠֲΛݟ͚ͭΔ 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
  68. ྠֲ ݀

  69. None
  70. Ұ൪େ͖ͳྠֲ max = contours.max_by { |c| c.contour_area }

  71. None
  72. ଟ֯ܗΛݟ͚ͭΔ approx = max.approx_poly(:method => :dp, :recursive => true, :accuracy

    => 0.02 * peri) x = approx.convex_hull2.to_a clockwise_points = clockwise x.reverse
  73. None
  74. ಁࢹม׵ͷߦྻ 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)
  75. ΠϝʔδΛม׵͢Δ new_img = img.warp_perspective transform

  76. None
  77. ڥք࠲ඪΛઃఆ͢Δ new_img.set_roi OpenCV::CvRect.new(0, 0, width, height)

  78. None
  79. It’s Just That Easy!

  80. ϢʔβʔΠϯλʔϑΣΠε ΧϝϥͰ ࡱͬͨ Πϝʔδ ਪଌ #1 ਪଌ #2 ਪଌ #3

  81. None
  82. Կ͕͋Δʁ Card.joins(:images) .where('images.type' => 'UserImage') .group('cards.name') .count

  83. Ͳͷ͙Β͍ྑ͍ʁ Card.joins(:images) # best .where('images.type' => 'UserImage') .order('rating desc').first Card.joins(:images)

    # worst .where('images.type' => 'UserImage') .order('rating asc').first
  84. ࠷ߴ:

  85. ࠷௿:

  86. ϓϩδΣΫτͷ໰୊

  87. য఺ͷ࣌ؒ

  88. None
  89. ࣦഊͷ࣌

  90. None
  91. ֆ͸ࣅͯΔ

  92. None
  93. अຐೣ

  94. None
  95. ར఺ ઃఆ͸؆୯ ඞཁϋʔυ΢ΣΞ͸͋·Γͳ͍ ͍҆ ΩϟϦϒϨʔτ͠ͳ͍

  96. ܽ఺ ෳࡶͳιϑτ΢ΣΞ ࿑ಇ ֬ೝͷ஗͞

  97. ࠓޙͷ׆ಈ

  98. ࣗಈԽ

  99. ੌ͍ίʔυ ڪΖ͍͠ / ා͍

  100. PHP + Ruby

  101. Phuby (ϑʔϏΟ) https://github.com/tenderlove/phuby એ఻

  102. Examples

  103. PHPͷ ΦϒδΣΫτΛ࢖͏

  104. ਺ࣈ require 'phuby' Phuby::Runtime.php do |runtime| runtime.eval "$v = strlen('PHP

    INSIDE OF RUBY');" puts runtime['v'] # => 18 end
  105. จࣈྻ require 'phuby' Phuby::Runtime.php do |runtime| runtime.eval "$name = 'Aaron';"

    puts runtime['name'] # => Aaron end
  106. ഑ྻ 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
  107. ࿈૝഑ྻ 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
  108. Rubyͷ ΦϒδΣΫτΛ࢖͏

  109. Objects require 'phuby' class RubyKaigi def where puts "౦ژ" end

    end Phuby::Runtime.php do |runtime| runtime['kaigi'] = RubyKaigi.new runtime.eval("$kaigi->where();") # => ౦ژ end
  110. ͳͥʁ

  111. ͍͍͔Β

  112. scientists were so preoccupied with whether or not they could

    that they didn't stop to think if they should.
  113. ϓϩάϥϜͷମܕ

  114. Runtime Proxy Object Map Ruby Object Proxy PHP Object Proxy

  115. Wrapper Access PHP Objects Ruby C PHP Object Map Ruby

    Proxy PHP Runtime Object
  116. Wrapper Access Ruby Objects Ruby C PHP Object Map Ruby

    Proxy PHP Runtime Object
  117. ϓϩδΣΫτͷ ໰୊

  118. PHPΛ ίϯύΠϧ͢Δ

  119. GC

  120. άϩʔόϧͷม਺

  121. ໰୊ 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 # => []
  122. 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", ... ]
  123. Rails Support

  124. PHP templates

  125. None
  126. Πϯελϯεม਺

  127. None
  128. ActiveRecord΋࢖͑·͢

  129. None
  130. How much would you pay for this?

  131. 200ԁ?

  132. 250ԁ?

  133. https://github.com/ tenderlove/phuby FREE!

  134. ൿີͷτϐοΫ

  135. ko1 said this is a tech conference, so you don’t

    have to tell any jokes
  136. So I won’t tell any jokes.

  137. ੌ͍ίʔυ How does it work?

  138. Homeopathic Optimizations

  139. Homeopathy ͱ͸ʁ

  140. رऍɻ

  141. ௕͗͢Δʂ

  142. None
  143. None
  144. Modern advocates of homeopathy have proposed a concept of "water

    memory", according to which water "remembers" the substances mixed in
  145. ਫ͸ هԱग़དྷ·͢

  146. ۭന΋ هԱ͢Δࣄ͕Ͱ͖Δʁ

  147. YES!

  148. σϞͷ࣌ؒ!

  149. None
  150. Ͳ͏΍ͬͯ ಈ͍ͯΔʁ

  151. VM ͸هԱ͢Δ

  152. ͦΕ͸ۭന͡Όͳ ͯ͘ɺهԱͩɻ

  153. ଞͷಛ௃

  154. None
  155. ར఺

  156. ߴ଎Խ

  157. "No code is faster than no code"

  158. رऍ͞ΕΕ͹͞ΕΔ΄Ͳ ϓϩάϥϜ͸ΑΓ଎͘ͳ Δ

  159. ҡ࣋

  160. ίʔυ͸ͳ͍͔Β

  161. THANK YOU!!!

  162. ࣭໰ʁ