GCRC 2014 - The Dark Side of Ruby

2,173 views

Published on

I love Ruby! But as in any relationship, to love means that you (often) have to accept the “dark side” too! Ruby is human in nature and has a lot of gotchas, tricks, wierdness and sometimes scary features that I plan to highlight. This talk aims to provide the “Ah-ha!” moments when working in Ruby.

This talk is for beginners and experts alike – in fact, I tag slides to mark their level and beginners can choose to tune out of the heavy stuff!

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
2,173
On SlideShare
0
From Embeds
0
Number of Embeds
224
Actions
Shares
0
Downloads
13
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

GCRC 2014 - The Dark Side of Ruby

  1. 1. The Dark Side of Ruby http://www.flickr.com/photos/sashapo/2722924752/sizes/l/
  2. 2. The Dark Side of Ruby @gautamrege! @joshsoftware http://www.flickr.com/photos/sashapo/2722924752/sizes/l/ since 2007
  3. 3. What’s the talk about? • Nothing scary • Weirdness and Gotcha’s Ah-ha! Moments
  4. 4. Slides are Tagged Beginner Expert
  5. 5. (In)Famous Infinity http://www.flickr.com/photos/emdot/482622478/sizes/l/
  6. 6. (In)famous Infinity $ irb> 1/0 => ZeroDivisionError: divided by 0 $ irb> 1.0/0 => Infinity $ irb> Infinity => NameError: uninitialized constant Infinity
  7. 7. Base Jumping http://www.flickr.com/photos/shahdi/8035647153/sizes/l/
  8. 8. Base Conversions $ irb> 12345.to_s(8) => "30071" # => Octal $ irb> 12345.to_s(36) => "9ix" # That is an actual number $ irb> 1234.to_s(64) => ArgumentError: invalid radix 64
  9. 9. The Star - *
  10. 10. Splat Expander Job = Struct.new(:name, :occupation) tom = Job.new("Tom", "Developer") name, occupation = *tom => ["Tom", "Developer"] => name # "Tom" => occupation # "Developer"
  11. 11. Splat Expander Job = Struct.new(:name, :occupation) tom = Job.new(occupation: "Developer", name: "Tom") name, occupation = *tom => name # {:occupation=>"Developer", :name=> "Tom"} => occupation # nil
  12. 12. Hashes and Arrays a=[1,2,3,4,5,6]! h=Hash[*a] => {1=>2, 3=>4, 5=>6} [1,2,3] * 3! => [1,2,3,1,2,3,1,2,3] [1,2,3] * "%"! => "1%2%3"
  13. 13. Calling out to Stabby blk = ->(f, *m, sl, l) do puts sl end blk.call(1, 2, 3, 4, 5, 6) => 5 blk.(1, 2, 3, 4, 5, 6) => 5 call is implied for a stabby proc or a Proc
  14. 14. The Case Statement def multiple_of(factor)! Proc.new {|p| p.modulo(factor).zero?}! end! ! number = 9! case number! when multiple_of(3)! puts "Multiple of 3"! when multiple_of(7)! puts "Multiple of 7"! end
  15. 15. Behind every case is a === number = 9! case number ! when multiple_of(3) Proc.new {|p| p.modulo(3).zero?} === 9 Proc#=== is an alias to Proc#call. Proc.new { |p| ! p.modulo(3).zero?! }.call(9)
  16. 16. Override the === method to customise case evaluation.
  17. 17. ==, ===, eql?, equal? http://www.flickr.com/photos/gak/2418146934/sizes/o/
  18. 18. ==, ===, eql?, equal? irb> 1 == 1.0 => true # generic equality irb> 1 === 1.0 => true # case equality irb> 1.eql? 1.0 => false # equality by value irb> 1.equal? 1.0 => false # object identity irb> 'a'.equal? 'a' => false # gotcha!
  19. 19. Proc#curry http://www.flickr.com/photos/miscdebris/6748016253/sizes/o/
  20. 20. 3 Pulls for the Jackpot jackpot = lambda { |x, y, z| (x == y) == (x == z) } ! # 3 pulls pull = jackpot.curry[rand(5)] 2.times { pull = pull.curry[rand(5)] } ! p pull ? "Jackpot" : "Sucker!"
  21. 21. The curry recipe pull = jackpot.curry[rand(5)] => #<Proc:0x007f9eec0990b0 (lambda)> • Return lambda till all parameters are passed. • Evaluate the block if all parameters are passed. 2.times { pull = pull.curry[rand(5)] } => true # or false
  22. 22. So! So you think you can tell… Protected from Private
  23. 23. Private methods class Base private def foo puts "inside foo" end Private Methods are end inherited! class Child < Base def bar foo end end
  24. 24. The elusive include class Base! include Mongoid::Document! end Private method! Instance method ! Defined the class Module
  25. 25. Protected methods • Work with objects not classes. • Invoke a protected method on another object in the same lineage What the …
  26. 26. class Autobot def initialize(nick); @nick = nick; end ! protected attr_accessor :nick end ! prime = Autobot.new("Optimus Prime") p prime.nick protected method `nick' called for #<Autobot:0x007f92ba082330 @nick="Optimus Prime"> (NoMethodError)
  27. 27. class Autobot def fights(target) p "I am #{self.nick}" p "Kicking #{target.nick}'s ass" end protected attr_accessor :nick end ! prime = Autobot.new("Optimus Prime") megatron = Autobot.new('Megatron') ! prime.fights megatron "I am Optimus Prime" "Kicking Megatron's ass"
  28. 28. Keywords in Ruby?
  29. 29. Keywords - hmm… class Serious def true false end def false true end end die = Serious.new p "seriously!" if die.false
  30. 30. Cherry pick from Modules module Megatron! def power! p "Megatron's super strength"! end! ! def evil! p 'Evil genius'! end! end
  31. 31. Cherry pick from Modules class Hanuman! include Megatron! end Hanuman.new.power! # => "Megatron's super strength"! Hanuman.new.evil ! # => "Evil genius" # Oh no!
  32. 32. Cherry pick from Modules class Hanuman! def power! Megatron.instance_method(:power).! bind(self).call! end! end Hanuman.new.power! # => "Megatron's super strength"! Hanuman.new.evil ! # => undefined method `evil’...>
  33. 33. That’s all Folks! @gautamrege @joshsoftware

×