Transcript
Page 1: RedDot Ruby Conf 2014 - Dark side of ruby

The Dark Side of Ruby

@gautamrege!@joshsoftware

Page 2: RedDot Ruby Conf 2014 - Dark side of ruby

What’s the talk about?

Page 3: RedDot Ruby Conf 2014 - Dark side of ruby

What’s the talk about?• Ruby is AWESOME but …

Page 4: RedDot Ruby Conf 2014 - Dark side of ruby

What’s the talk about?• Ruby is AWESOME but …

• Nothing scary

Page 5: RedDot Ruby Conf 2014 - Dark side of ruby

What’s the talk about?• Ruby is AWESOME but …

• Nothing scary really

Page 6: RedDot Ruby Conf 2014 - Dark side of ruby

What’s the talk about?• Ruby is AWESOME but …

• Nothing scary

• Weirdness and Gotcha’s

really

Page 7: RedDot Ruby Conf 2014 - Dark side of ruby

What’s the talk about?• Ruby is AWESOME but …

• Nothing scary

• Weirdness and Gotcha’s

Ah-ha! Moments

really

Page 8: RedDot Ruby Conf 2014 - Dark side of ruby

Slides are Tagged

Page 9: RedDot Ruby Conf 2014 - Dark side of ruby

Slides are Tagged

Beginner

Page 10: RedDot Ruby Conf 2014 - Dark side of ruby

Slides are Tagged

Expert

Page 11: RedDot Ruby Conf 2014 - Dark side of ruby

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

Page 12: RedDot Ruby Conf 2014 - Dark side of ruby

(In)Famous Infinity

Page 13: RedDot Ruby Conf 2014 - Dark side of ruby

(In)Famous Infinity

Page 14: RedDot Ruby Conf 2014 - Dark side of ruby

(In)Famous Infinity$ irb> 1/0

Page 15: RedDot Ruby Conf 2014 - Dark side of ruby

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

Page 16: RedDot Ruby Conf 2014 - Dark side of ruby

(In)Famous Infinity$ irb> 1/0

$ irb> 1.0/0

=> ZeroDivisionError: divided by 0

Page 17: RedDot Ruby Conf 2014 - Dark side of ruby

(In)Famous Infinity$ irb> 1/0

$ irb> 1.0/0

=> ZeroDivisionError: divided by 0

=> Infinity

Page 18: RedDot Ruby Conf 2014 - Dark side of ruby

(In)Famous Infinity$ irb> 1/0

$ irb> 1.0/0

$ irb> Infinity

=> ZeroDivisionError: divided by 0

=> Infinity

Page 19: RedDot Ruby Conf 2014 - Dark side of ruby

(In)Famous Infinity$ irb> 1/0

$ irb> 1.0/0

$ irb> Infinity

=> ZeroDivisionError: divided by 0

=> Infinity

=> NameError: uninitialized constant Infinity

Page 20: RedDot Ruby Conf 2014 - Dark side of ruby

(In)Famous Infinity

Page 21: RedDot Ruby Conf 2014 - Dark side of ruby

(In)Famous Infinity

Page 22: RedDot Ruby Conf 2014 - Dark side of ruby

(In)Famous Infinity#if !defined(INFINITY) || !defined(NAN)!union bytesequence4_or_float {! unsigned char bytesequence[4];! float float_value;!};!#endif!!RUBY_EXTERN const union bytesequence4_or_float rb_infinity;

Page 23: RedDot Ruby Conf 2014 - Dark side of ruby

(In)Famous Infinity#if !defined(INFINITY) || !defined(NAN)!union bytesequence4_or_float {! unsigned char bytesequence[4];! float float_value;!};!#endif!!RUBY_EXTERN const union bytesequence4_or_float rb_infinity;

include/ruby/missing.h

Page 24: RedDot Ruby Conf 2014 - Dark side of ruby

Base Jumping

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

Page 25: RedDot Ruby Conf 2014 - Dark side of ruby

Base Conversions

Page 26: RedDot Ruby Conf 2014 - Dark side of ruby

Base Conversions

Page 27: RedDot Ruby Conf 2014 - Dark side of ruby

Base Conversions$ irb> 12345.to_s(8)

Page 28: RedDot Ruby Conf 2014 - Dark side of ruby

Base Conversions$ irb> 12345.to_s(8)=> "30071" # => Octal

Page 29: RedDot Ruby Conf 2014 - Dark side of ruby

Base Conversions$ irb> 12345.to_s(8)

$ irb> 12345.to_s(36)

=> "30071" # => Octal

Page 30: RedDot Ruby Conf 2014 - Dark side of ruby

Base Conversions$ irb> 12345.to_s(8)

$ irb> 12345.to_s(36)

=> "30071" # => Octal

=> "9ix" # That is an actual number

Page 31: RedDot Ruby Conf 2014 - Dark side of ruby

Base Conversions$ irb> 12345.to_s(8)

$ irb> 12345.to_s(36)

$ irb> 1234.to_s(64)

=> "30071" # => Octal

=> "9ix" # That is an actual number

Page 32: RedDot Ruby Conf 2014 - Dark side of ruby

Base Conversions$ irb> 12345.to_s(8)

$ irb> 12345.to_s(36)

$ irb> 1234.to_s(64)

=> "30071" # => Octal

=> "9ix" # That is an actual number

=> ArgumentError: invalid radix 64

Page 33: RedDot Ruby Conf 2014 - Dark side of ruby
Page 34: RedDot Ruby Conf 2014 - Dark side of ruby

Hashes and Arrays

Page 35: RedDot Ruby Conf 2014 - Dark side of ruby

Hashes and Arrays

Page 36: RedDot Ruby Conf 2014 - Dark side of ruby

Hashes and Arraysa=[1,2,3,4,5,6]!h=Hash[*a]

Page 37: RedDot Ruby Conf 2014 - Dark side of ruby

Hashes and Arraysa=[1,2,3,4,5,6]!h=Hash[*a]=> {1=>2, 3=>4, 5=>6}

Page 38: RedDot Ruby Conf 2014 - 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

Page 39: RedDot Ruby Conf 2014 - 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]

Page 40: RedDot Ruby Conf 2014 - 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] * "%"

Page 41: RedDot Ruby Conf 2014 - 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 42: RedDot Ruby Conf 2014 - Dark side of ruby

Calling out to Stabby

Page 43: RedDot Ruby Conf 2014 - Dark side of ruby

Calling out to Stabbyblk = ->(f, *m, sl, l) do puts sl end

Page 44: RedDot Ruby Conf 2014 - Dark side of ruby

Calling out to Stabbyblk = ->(f, *m, sl, l) do puts sl end

blk.call(1, 2, 3, 4, 5, 6)

Page 45: RedDot Ruby Conf 2014 - 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

Page 46: RedDot Ruby Conf 2014 - Dark side of ruby

blk.(1, 2, 3, 4, 5, 6)

Calling out to Stabbyblk = ->(f, *m, sl, l) do puts sl end

blk.call(1, 2, 3, 4, 5, 6)=> 5

Page 47: RedDot Ruby Conf 2014 - Dark side of ruby

blk.(1, 2, 3, 4, 5, 6)

Calling out to Stabbyblk = ->(f, *m, sl, l) do puts sl end

blk.call(1, 2, 3, 4, 5, 6)=> 5

Page 48: RedDot Ruby Conf 2014 - Dark side of ruby

blk.(1, 2, 3, 4, 5, 6)=> 5

syntax sugar for call blk[1,2,3,4,5,6]

Calling out to Stabbyblk = ->(f, *m, sl, l) do puts sl end

blk.call(1, 2, 3, 4, 5, 6)=> 5

Page 49: RedDot Ruby Conf 2014 - Dark side of ruby

Syntax

Page 50: RedDot Ruby Conf 2014 - Dark side of ruby

Syntax def foo(a=1, b=1,opts={})

end

Page 51: RedDot Ruby Conf 2014 - Dark side of ruby

Syntax def foo(a: 1, b: 2)

end

Page 52: RedDot Ruby Conf 2014 - Dark side of ruby

Syntax def foo(a: 1, b: 2)

endkeyword arguments

Page 53: RedDot Ruby Conf 2014 - Dark side of ruby

Syntax

def foo(a: 1, b:, c: 2)

end

def foo(a: 1, b: 2)

endkeyword arguments

Page 54: RedDot Ruby Conf 2014 - Dark side of ruby

Syntax

def foo(a: 1, b:, c: 2)

end

def foo(a: 1, b: 2)

endkeyword arguments

Page 55: RedDot Ruby Conf 2014 - Dark side of ruby

Syntax

def foo(a: 1, b:, c: 2)

end

foo(a: 2) => ArgumentError: missing keyword: b

Mandatory keyword arguments

def foo(a: 1, b: 2)

endkeyword arguments

Page 56: RedDot Ruby Conf 2014 - Dark side of ruby

Syntax

Page 57: RedDot Ruby Conf 2014 - Dark side of ruby

Syntaxdef foo(a, b) p a, b

end

Page 58: RedDot Ruby Conf 2014 - Dark side of ruby

Syntaxdef foo(a, b) p a, b

end

foo (1, 2)

Page 59: RedDot Ruby Conf 2014 - Dark side of ruby

Syntaxdef foo(a, b) p a, b

end

foo (1, 2)syntax error, unexpected

',', expecting ')'

Page 60: RedDot Ruby Conf 2014 - Dark side of ruby

Syntaxdef foo(a, b) p a, b

end

foo (1, 2)

foo(1, 2)

Page 61: RedDot Ruby Conf 2014 - Dark side of ruby

Syntaxdef foo(a, b) p a, b

end

foo (1, 2)

foo(1, 2)

Page 62: RedDot Ruby Conf 2014 - Dark side of ruby

Syntaxdef foo(a, b) p a, b

end

foo (1, 2)

foo(1, 2) syntax error, unexpected ',', expecting ')'

Page 63: RedDot Ruby Conf 2014 - Dark side of ruby

Syntax

Page 64: RedDot Ruby Conf 2014 - Dark side of ruby

Syntaxirb> a[1]

What is the data type of a ?

Page 65: RedDot Ruby Conf 2014 - Dark side of ruby

Syntaxirb> a[1]

a = [ 10, 11, 12] # Array

Page 66: RedDot Ruby Conf 2014 - Dark side of ruby

Syntaxirb> a[1]

a = [ 10, 11, 12] # Array

a = { 1 => "one" } # Hash

Page 67: RedDot Ruby Conf 2014 - Dark side of ruby

Syntaxirb> a[1]

a = [ 10, 11, 12] # Array

a = { 1 => "one" } # Hash

a = Proc.new { |e| p e }

Page 68: RedDot Ruby Conf 2014 - Dark side of ruby

Case Complexity

Page 69: RedDot Ruby Conf 2014 - 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 70: RedDot Ruby Conf 2014 - 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 71: RedDot Ruby Conf 2014 - 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

Page 72: RedDot Ruby Conf 2014 - 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

Page 73: RedDot Ruby Conf 2014 - 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#=== is an alias to Proc#call.

Page 74: RedDot Ruby Conf 2014 - 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 75: RedDot Ruby Conf 2014 - Dark side of ruby

Override the === method to customise case

evaluation.

Page 76: RedDot Ruby Conf 2014 - Dark side of ruby

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

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

Page 77: RedDot Ruby Conf 2014 - Dark side of ruby

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

Page 78: RedDot Ruby Conf 2014 - Dark side of ruby

==, ===, eql?, equal?irb> 1 == 1.0

Page 79: RedDot Ruby Conf 2014 - Dark side of ruby

==, ===, eql?, equal?irb> 1 == 1.0=> true # generic equality

Page 80: RedDot Ruby Conf 2014 - Dark side of ruby

==, ===, eql?, equal?irb> 1 == 1.0=> true # generic equalityirb> 1 === 1.0

Page 81: RedDot Ruby Conf 2014 - Dark side of ruby

==, ===, eql?, equal?irb> 1 == 1.0=> true # generic equalityirb> 1 === 1.0=> true # case equality

Page 82: RedDot Ruby Conf 2014 - Dark side of ruby

==, ===, eql?, equal?irb> 1 == 1.0=> true # generic equalityirb> 1 === 1.0=> true # case equalityirb> 1.eql? 1.0

Page 83: RedDot Ruby Conf 2014 - Dark side of ruby

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

=> false # alias of == except Numeric

irb> 1 == 1.0=> true # generic equalityirb> 1 === 1.0=> true # case equalityirb> 1.eql? 1.0

Page 84: RedDot Ruby Conf 2014 - Dark side of ruby

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

=> false # alias of == except Numeric

irb> 1 == 1.0=> true # generic equalityirb> 1 === 1.0=> true # case equalityirb> 1.eql? 1.0

irb> 1.equal? 1.0

Page 85: RedDot Ruby Conf 2014 - Dark side of ruby

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

=> false # alias of == except Numeric

irb> 1 == 1.0=> true # generic equalityirb> 1 === 1.0=> true # case equalityirb> 1.eql? 1.0

irb> 1.equal? 1.0=> false # object identity

Page 86: RedDot Ruby Conf 2014 - Dark side of ruby

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

=> false # alias of == except Numeric

irb> 1 == 1.0=> true # generic equalityirb> 1 === 1.0=> true # case equalityirb> 1.eql? 1.0

irb> 1.equal? 1.0=> false # object identityirb> 'a'.equal? 'a'

Page 87: RedDot Ruby Conf 2014 - Dark side of ruby

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

=> false # alias of == except Numeric

=> false # gotcha?

irb> 1 == 1.0=> true # generic equalityirb> 1 === 1.0=> true # case equalityirb> 1.eql? 1.0

irb> 1.equal? 1.0=> false # object identityirb> 'a'.equal? 'a'

Page 88: RedDot Ruby Conf 2014 - Dark side of ruby

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

=> false # alias of == except Numeric

=> false # gotcha?

irb> 1 == 1.0=> true # generic equalityirb> 1 === 1.0=> true # case equalityirb> 1.eql? 1.0

irb> 1.equal? 1.0=> false # object identityirb> 'a'.equal? 'a'

irb> 1.equal? 1

Page 89: RedDot Ruby Conf 2014 - Dark side of ruby

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

=> false # alias of == except Numeric

=> false # gotcha?

irb> 1 == 1.0=> true # generic equalityirb> 1 === 1.0=> true # case equalityirb> 1.eql? 1.0

irb> 1.equal? 1.0=> false # object identityirb> 'a'.equal? 'a'

=> true # gotcha?irb> 1.equal? 1

Page 90: RedDot Ruby Conf 2014 - Dark side of ruby

Object Ids & Fixnum

Page 91: RedDot Ruby Conf 2014 - Dark side of ruby

Object Ids & Fixnum

Fixnum * 2 + 1irb> 23 * 2 + 1 => 47 irb > 23.object_id => 47

Page 92: RedDot Ruby Conf 2014 - Dark side of ruby

Object Ids & Fixnum

Fixnum * 2 + 1irb> 23 * 2 + 1 => 47 irb > 23.object_id => 47

irb> (2**62 - 1).class => Fixnum irb> (2**62).class => Bignum

Page 93: RedDot Ruby Conf 2014 - Dark side of ruby

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

Page 94: RedDot Ruby Conf 2014 - 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 95: RedDot Ruby Conf 2014 - 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 96: RedDot Ruby Conf 2014 - 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 97: RedDot Ruby Conf 2014 - 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 98: RedDot Ruby Conf 2014 - 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 99: RedDot Ruby Conf 2014 - Dark side of ruby

So! So you think you can tell…

Heaven from Hell- Pink Floyd

Page 100: RedDot Ruby Conf 2014 - Dark side of ruby

So! So you think you can tell…

Protected from Private

Page 101: RedDot Ruby Conf 2014 - Dark side of ruby

Private methodsclass Soldier private def ryan puts "Saving private ryan" end end class Movie < Soldier def name ryan end end

Page 102: RedDot Ruby Conf 2014 - Dark side of ruby

Private methodsclass Soldier private def ryan puts "Saving private ryan" end end class Movie < Soldier def name ryan end end

Page 103: RedDot Ruby Conf 2014 - Dark side of ruby

Private methodsclass Soldier private def ryan puts "Saving private ryan" end end class Movie < Soldier def name ryan end end

Private Methods are inherited!

Page 104: RedDot Ruby Conf 2014 - Dark side of ruby

class Base! include Mongoid::Document!end

The elusive include

Page 105: RedDot Ruby Conf 2014 - Dark side of ruby

class Base! include Mongoid::Document!end

The elusive include

Page 106: RedDot Ruby Conf 2014 - Dark side of ruby

Private method!Instance method !

Defined the class Module

class Base! include Mongoid::Document!end

The elusive include

Page 107: RedDot Ruby Conf 2014 - Dark side of ruby

Protected methods

Page 108: RedDot Ruby Conf 2014 - Dark side of ruby

Protected methods

Page 109: RedDot Ruby Conf 2014 - Dark side of ruby

Protected methods

• Work with objects not classes.

Page 110: RedDot Ruby Conf 2014 - Dark side of ruby

Protected methods

• Work with objects not classes.

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

Page 111: RedDot Ruby Conf 2014 - 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 112: RedDot Ruby Conf 2014 - 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

Page 113: RedDot Ruby Conf 2014 - 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

Page 114: RedDot Ruby Conf 2014 - 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 115: RedDot Ruby Conf 2014 - 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 !optimus = Autobot.new("Optimus Prime") megatron = Autobot.new('Megatron') !optimus.fights megatron

Page 116: RedDot Ruby Conf 2014 - 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 !optimus = Autobot.new("Optimus Prime") megatron = Autobot.new('Megatron') !optimus.fights megatron

Page 117: RedDot Ruby Conf 2014 - 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 !optimus = Autobot.new("Optimus Prime") megatron = Autobot.new('Megatron') !optimus.fights megatron

"I am Optimus Prime" "Kicking Megatron's ass"

Page 118: RedDot Ruby Conf 2014 - 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 !optimus = Autobot.new("Optimus Prime") megatron = Autobot.new('Megatron') !optimus.fights megatron

"I am Optimus Prime" "Kicking Megatron's ass"

Page 119: RedDot Ruby Conf 2014 - Dark side of ruby

Keywords in Ruby?

Page 120: RedDot Ruby Conf 2014 - 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 121: RedDot Ruby Conf 2014 - 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 122: RedDot Ruby Conf 2014 - 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

stack too deep?

Page 123: RedDot Ruby Conf 2014 - Dark side of ruby

superlativeclass Search! def search! p "Default Search algorithm"! end!end!class KeywordSearch < Search ! def search(keyword:)! super! end!end!KeywordSearch.new.search(keyword: "Ruby")

Page 124: RedDot Ruby Conf 2014 - Dark side of ruby

superlativeclass Search! def search! p "Default Search algorithm"! end!end!class KeywordSearch < Search ! def search(keyword:)! super! end!end!KeywordSearch.new.search(keyword: "Ruby")

Page 125: RedDot Ruby Conf 2014 - Dark side of ruby

superlativeclass Search! def search! p "Default Search algorithm"! end!end!class KeywordSearch < Search ! def search(keyword:)! super! end!end!KeywordSearch.new.search(keyword: "Ruby")

Page 126: RedDot Ruby Conf 2014 - Dark side of ruby

superlativeclass Search! def search! p "Default Search algorithm"! end!end!class KeywordSearch < Search ! def search(keyword:)! super! end!end!KeywordSearch.new.search(keyword: "Ruby")

`search`: wrong number of arguments (1 for 0)

Page 127: RedDot Ruby Conf 2014 - Dark side of ruby

superlativeclass Search! def search! p "Default Search algorithm"! end!end!class KeywordSearch < Search ! def search(keyword:)! super()! end!end!KeywordSearch.new.search(keyword: "Ruby")

Page 128: RedDot Ruby Conf 2014 - Dark side of ruby

superlativeclass Search! def search! p "Default Search algorithm"! end!end!class KeywordSearch < Search ! def search(keyword:)! super()! end!end!KeywordSearch.new.search(keyword: "Ruby")

Page 129: RedDot Ruby Conf 2014 - Dark side of ruby

superlativeclass Search! def search! p "Default Search algorithm"! end!end!class KeywordSearch < Search ! def search(keyword:)! super()! end!end!KeywordSearch.new.search(keyword: "Ruby")

Page 130: RedDot Ruby Conf 2014 - Dark side of ruby

superlativeclass Search! def search! p "Default Search algorithm"! end!end!class KeywordSearch < Search ! def search(keyword:)! super()! end!end!KeywordSearch.new.search(keyword: "Ruby")

And we thought parenthesis for method invocation didn’t matter

Page 131: RedDot Ruby Conf 2014 - Dark side of ruby

Module mixins are funnymodule Superman! def fly; p "Superman: It's a bird"; end!end!!module Batman! def fly; p "Batman: Fly? Me?"; end!end!!module Ironman! def fly; p "Iroman: That's flying!"; end!end

Page 132: RedDot Ruby Conf 2014 - Dark side of ruby

Module mixins are funnymodule Superman! def fly; p "Superman: It's a bird"; end!end!!module Batman! def fly; p "Batman: Fly? Me?"; end!end!!module Ironman! def fly; p "Iroman: That's flying!"; end!end

Page 133: RedDot Ruby Conf 2014 - Dark side of ruby

Module mixins are funnyclass Tinyman! include Superman! include Batman! include Ironman!end!!Tinyman.new.fly

"Iroman: That's how you fly!"

Page 134: RedDot Ruby Conf 2014 - Dark side of ruby

Module mixins are funnyclass Tinyman! include Superman! include Batman! include Ironman!end!!Tinyman.new.fly

"Iroman: That's how you fly!"

Page 135: RedDot Ruby Conf 2014 - Dark side of ruby

Module Inheritance?module Superman! def fly; p "Superman: It's a bird"; end!end!!module Batman! def fly; p "Batman: Fly? Me?"; end!end!!module Ironman! def fly; super; p "Iroman: That's flying!"; end!end

Page 136: RedDot Ruby Conf 2014 - Dark side of ruby

Module Inheritance?module Superman! def fly; p "Superman: It's a bird"; end!end!!module Batman! def fly; p "Batman: Fly? Me?"; end!end!!module Ironman! def fly; super; p "Iroman: That's flying!"; end!end

Page 137: RedDot Ruby Conf 2014 - Dark side of ruby

Module Inheritance?module Superman! def fly; p "Superman: It's a bird"; end!end!!module Batman! def fly; p "Batman: Fly? Me?"; end!end!!module Ironman! def fly; super; p "Iroman: That's flying!"; end!end

"Batman: Fly? Me?”!"Iroman: That's flying!"

Page 138: RedDot Ruby Conf 2014 - Dark side of ruby

Dynamic Inheritance!class Tinyman! include Superman! include Batman! include Ironman!end

Page 139: RedDot Ruby Conf 2014 - Dark side of ruby

Dynamic Inheritance!class Tinyman! include Superman! include Batman! include Ironman!end

Page 140: RedDot Ruby Conf 2014 - Dark side of ruby

class Tinyman! include Superman! include Ironman! include Batman!end

Dynamic Inheritance!class Tinyman! include Superman! include Batman! include Ironman!end

Page 141: RedDot Ruby Conf 2014 - Dark side of ruby

class Tinyman! include Superman! include Ironman! include Batman!end

Dynamic Inheritance!class Tinyman! include Superman! include Batman! include Ironman!end

Page 142: RedDot Ruby Conf 2014 - 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 143: RedDot Ruby Conf 2014 - 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 144: RedDot Ruby Conf 2014 - Dark side of ruby

class Hanuman! include Megatron!end

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

Cherry pick from Modules

Page 145: RedDot Ruby Conf 2014 - Dark side of ruby

class Hanuman! include Megatron!end

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

Cherry pick from Modules

Page 146: RedDot Ruby Conf 2014 - Dark side of ruby

Cherry pick from Modulesclass Hanuman! def power! Megatron.instance_method(:power).! bind(self).call! end!end

Page 147: RedDot Ruby Conf 2014 - Dark side of ruby

Cherry pick from Modulesclass Hanuman! def power! Megatron.instance_method(:power).! bind(self).call! end!end

Page 148: RedDot Ruby Conf 2014 - 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 149: RedDot Ruby Conf 2014 - Dark side of ruby

That’s all Folks!

@gautamrege @joshsoftware

Page 150: RedDot Ruby Conf 2014 - Dark side of ruby

That’s all Folks!

@gautamrege @joshsoftware

since 2007


Recommended