gcrc 2014 - the dark side of ruby

33
http://www.flickr.com/photos/sashapo/2722924752/sizes/l/ The Dark Side of Ruby

Upload: gautam-rege

Post on 10-May-2015

1.636 views

Category:

Technology


1 download

DESCRIPTION

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!

TRANSCRIPT

Page 1: GCRC 2014 - The Dark Side of Ruby

http://www.flickr.com/photos/sashapo/2722924752/sizes/l/

The Dark Side of Ruby

Page 2: GCRC 2014 - The Dark Side of Ruby

http://www.flickr.com/photos/sashapo/2722924752/sizes/l/

The Dark Side of Ruby

@gautamrege!@joshsoftware since 2007

Page 3: GCRC 2014 - The Dark Side of Ruby

What’s the talk about?

• Nothing scary

• Weirdness and Gotcha’s

Ah-ha! Moments

Page 4: GCRC 2014 - The Dark Side of Ruby

Slides are Tagged

Beginner Expert

Page 5: GCRC 2014 - The Dark Side of Ruby

(In)Famous Infinityhttp://www.flickr.com/photos/emdot/482622478/sizes/l/

Page 6: GCRC 2014 - The Dark Side of Ruby

(In)famous Infinity$ irb> 1/0 => ZeroDivisionError: divided by 0

$ irb> 1.0/0 => Infinity

$ irb> Infinity => NameError: uninitialized constant Infinity

Page 7: GCRC 2014 - The Dark Side of Ruby

Base Jumping

http://www.flickr.com/photos/shahdi/8035647153/sizes/l/

Page 8: GCRC 2014 - The Dark Side of Ruby

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

Page 9: GCRC 2014 - The Dark Side of Ruby

The Star - *

Page 10: GCRC 2014 - The Dark Side of Ruby

Splat ExpanderJob = Struct.new(:name, :occupation) tom = Job.new("Tom", "Developer") name, occupation = *tom

=> ["Tom", "Developer"] => name # "Tom" => occupation # "Developer"

Page 11: GCRC 2014 - The Dark Side of Ruby

Splat ExpanderJob = Struct.new(:name, :occupation) tom = Job.new(occupation: "Developer", name: "Tom") name, occupation = *tom

=> name # {:occupation=>"Developer", :name=> "Tom"} => occupation # nil

Page 12: GCRC 2014 - The Dark Side of Ruby

Hashes and Arraysa=[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"

Page 13: GCRC 2014 - The Dark Side of Ruby

Calling out to Stabbyblk = ->(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

Page 14: GCRC 2014 - The Dark Side of Ruby

The Case Statementdef 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

Page 15: GCRC 2014 - The Dark Side of Ruby

Behind every case is a ===number = 9!case number ! when multiple_of(3)

Proc.new {|p| p.modulo(3).zero?} === 9

Proc.new { |p| ! p.modulo(3).zero?!}.call(9)

Proc#=== is an alias to Proc#call.

Page 16: GCRC 2014 - The Dark Side of Ruby

Override the === method to customise case

evaluation.

Page 17: GCRC 2014 - The Dark Side of Ruby

==, ===, eql?, equal?

http://www.flickr.com/photos/gak/2418146934/sizes/o/

Page 18: GCRC 2014 - The Dark Side of Ruby

==, ===, eql?, equal?irb> 1 == 1.0 => true # generic equality irb> 1 === 1.0 => true # case equality irb> 1.eql? 1.0 => false # equality by valueirb> 1.equal? 1.0 => false # object identity irb> 'a'.equal? 'a' => false # gotcha!

Page 19: GCRC 2014 - The Dark Side of Ruby

Proc#curry

http://www.flickr.com/photos/miscdebris/6748016253/sizes/o/

Page 20: GCRC 2014 - The Dark Side of Ruby

3 Pulls for the Jackpotjackpot = 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!"

Page 21: GCRC 2014 - The Dark Side of Ruby

The curry recipe

• Return lambda till all parameters are passed.

• Evaluate the block if all parameters are passed.

pull = jackpot.curry[rand(5)] => #<Proc:0x007f9eec0990b0 (lambda)>

2.times { pull = pull.curry[rand(5)] } => true # or false

Page 22: GCRC 2014 - The Dark Side of Ruby

So! So you think you can tell…

Protected from Private

Page 23: GCRC 2014 - The Dark Side of Ruby

Private methodsclass Base private def foo puts "inside foo" end end class Child < Base def bar foo end end

Private Methods are inherited!

Page 24: GCRC 2014 - The Dark Side of Ruby

Private method!Instance method !

Defined the class Module

class Base! include Mongoid::Document!end

The elusive include

Page 25: GCRC 2014 - The Dark Side of Ruby

Protected methods

• Work with objects not classes.

• Invoke a protected method on another object in the same lineage

What the …

Page 26: GCRC 2014 - The Dark Side of Ruby

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)

Page 27: GCRC 2014 - The Dark Side of Ruby

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"

Page 28: GCRC 2014 - The Dark Side of Ruby

Keywords in Ruby?

Page 29: GCRC 2014 - The Dark Side of Ruby

Keywords - hmm…class Serious def true false end def false true end end die = Serious.new p "seriously!" if die.false

Page 30: GCRC 2014 - The Dark Side of Ruby

Cherry pick from Modules

module Megatron! def power! p "Megatron's super strength"! end!!

def evil! p 'Evil genius'! end!end

Page 31: GCRC 2014 - The Dark Side of Ruby

Cherry pick from Modulesclass Hanuman! include Megatron!end

Hanuman.new.power!# => "Megatron's super strength"!Hanuman.new.evil !# => "Evil genius" # Oh no!

Page 32: GCRC 2014 - The Dark Side of Ruby

Cherry pick from Modulesclass 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’...>

Page 33: GCRC 2014 - The Dark Side of Ruby

That’s all Folks!@gautamrege @joshsoftware