The Dark Side of Ruby
@gautamrege!
@joshsoftware
What’s the talk about?
What’s the talk about?
• Ruby is AWESOME but …
What’s the talk about?
• Ruby is AWESOME but …
• Nothing scary
What’s the talk about?
• Ruby is AWESOME but …
• Nothing scary really
What’s the talk about?
• Ruby is AWESOME but …
• Nothing scary
• Weirdness and Gotcha’s
really
What’s the talk about?
• Ruby is AWESOME but …
• Nothing scary
• Weirdness and Gotcha’s
Ah-ha! Moments
really
Slides are Tagged
Slides are Tagged
Beginner
Slides are Tagged
Expert
(In)Famous Infinityhttp://www.flickr.com/photos/emdot/482622478/sizes/l/
(In)Famous Infinity
(In)Famous Infinity
(In)Famous Infinity
$ irb> 1/0
(In)Famous Infinity
$ irb> 1/0
=> ZeroDivisionError: divided by 0
(In)Famous Infinity
$ irb> 1/0
$ irb> 1.0/0
=> ZeroDivisionError: divided by 0
(In)Famous Infinity
$ irb> 1/0
$ irb> 1.0/0
=> ZeroDivisionError: divided by 0
=> Infinity
(In)Famous Infinity
$ irb> 1/0
$ irb> 1.0/0
$ irb> Infinity
=> ZeroDivisionError: divided by 0
=> Infinity
(In)Famous Infinity
$ irb> 1/0
$ irb> 1.0/0
$ irb> Infinity
=> ZeroDivisionError: divided by 0
=> Infinity
=> NameError: un...
(In)Famous Infinity
(In)Famous Infinity
#if !defined(INFINITY) || !defined(NAN)!
union bytesequence4_or_float {!
unsigned char bytesequence[4];...
(In)Famous Infinity
#if !defined(INFINITY) || !defined(NAN)!
union bytesequence4_or_float {!
unsigned char bytesequence[4];...
Base Jumping
http://www.flickr.com/photos/shahdi/8035647153/sizes/l/
Base Conversions
Base Conversions
Base Conversions
$ irb> 12345.to_s(8)
Base Conversions
$ irb> 12345.to_s(8)
=> "30071" # => Octal
Base Conversions
$ irb> 12345.to_s(8)
$ irb> 12345.to_s(36)
=> "30071" # => Octal
Base Conversions
$ irb> 12345.to_s(8)
$ irb> 12345.to_s(36)
=> "30071" # => Octal
=> "9ix" # That is an actual number
Base Conversions
$ irb> 12345.to_s(8)
$ irb> 12345.to_s(36)
$ irb> 1234.to_s(64)
=> "30071" # => Octal
=> "9ix" # That is ...
Base Conversions
$ irb> 12345.to_s(8)
$ irb> 12345.to_s(36)
$ irb> 1234.to_s(64)
=> "30071" # => Octal
=> "9ix" # That is ...
Splat Expander
Splat Expander
Splat Expander
Job = Struct.new(:name, :occupation)
tom = Job.new("Tom", "Developer")
name, occupation = *tom
Splat Expander
Job = Struct.new(:name, :occupation)
tom = Job.new("Tom", "Developer")
name, occupation = *tom
=> ["Tom", "...
Splat Expander
Splat Expander
Job = Struct.new(:name, :occupation)
tom = Job.new(occupation: "Developer",
name: "Tom")
name, occupation =...
Splat Expander
Job = Struct.new(:name, :occupation)
tom = Job.new(occupation: "Developer",
name: "Tom")
name, occupation =...
Hashes and Arrays
Hashes and Arrays
Hashes and Arrays
a=[1,2,3,4,5,6]!
h=Hash[*a]
Hashes and Arrays
a=[1,2,3,4,5,6]!
h=Hash[*a]
=> {1=>2, 3=>4, 5=>6}
Hashes and Arrays
a=[1,2,3,4,5,6]!
h=Hash[*a]
=> {1=>2, 3=>4, 5=>6}
[1,2,3] * 3
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]
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] * "%"
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...
Calling out to Stabby
Calling out to Stabby
blk = ->(f, *m, sl, l) do
puts sl
end
Calling out to Stabby
blk = ->(f, *m, sl, l) do
puts sl
end
blk.call(1, 2, 3, 4, 5, 6)
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)
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)
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
syntax sugar for call
blk[1,2,3,4,5,6]
Calling out to Stabby
blk = ->(f, *m, sl, l) do
puts sl...
Syntax
Syntax
def foo(a=1, b=1,opts={})
end
Syntax
def foo(a: 1, b: 2)
end
keyword arguments
Syntax
def foo(a: 1, b:, c: 2)
end
def foo(a: 1, b: 2)
end
keyword arguments
Syntax
def foo(a: 1, b:, c: 2)
end
def foo(a: 1, b: 2)
end
keyword arguments
Syntax
def foo(a: 1, b:, c: 2)
end
foo(a: 2)
=> ArgumentError: missing keyword: b
Mandatory keyword
arguments
def foo(a: 1...
Case Complexity
The Case Statement
def multiple_of(factor)!
Proc.new {|p| p.modulo(factor).zero?}!
end!
!
number = 9!
case number!
when mu...
The Case Statement
def multiple_of(factor)!
Proc.new {|p| p.modulo(factor).zero?}!
end!
!
number = 9!
case number!
when mu...
Behind every case is a ===
number = 9!
case number !
when multiple_of(3)
Proc.new {|p| p.modulo(3).zero?} === 9
Behind every case is a ===
number = 9!
case number !
when multiple_of(3)
Proc.new {|p| p.modulo(3).zero?} === 9
Behind every case is a ===
number = 9!
case number !
when multiple_of(3)
Proc.new {|p| p.modulo(3).zero?} === 9
Proc#=== i...
Behind every case is a ===
number = 9!
case number !
when multiple_of(3)
Proc.new {|p| p.modulo(3).zero?} === 9
Proc.new {...
Override the === method
to customise case
evaluation.
==, ===, eql?, equal?
http://www.flickr.com/photos/gak/2418146934/sizes/o/
==, ===, eql?, equal?
==, ===, eql?, equal?
irb> 1 == 1.0
==, ===, eql?, equal?
irb> 1 == 1.0
=> true # generic equality
==, ===, eql?, equal?
irb> 1 == 1.0
=> true # generic equality
irb> 1 === 1.0
==, ===, eql?, equal?
irb> 1 == 1.0
=> true # generic equality
irb> 1 === 1.0
=> true # case equality
==, ===, eql?, equal?
irb> 1 == 1.0
=> true # generic equality
irb> 1 === 1.0
=> true # case equality
irb> 1.eql? 1.0
==, ===, eql?, equal?
=> false # equality by value
irb> 1 == 1.0
=> true # generic equality
irb> 1 === 1.0
=> true # case ...
==, ===, eql?, equal?
=> false # equality by value
irb> 1 == 1.0
=> true # generic equality
irb> 1 === 1.0
=> true # case ...
==, ===, eql?, equal?
=> false # equality by value
irb> 1 == 1.0
=> true # generic equality
irb> 1 === 1.0
=> true # case ...
==, ===, eql?, equal?
=> false # equality by value
irb> 1 == 1.0
=> true # generic equality
irb> 1 === 1.0
=> true # case ...
==, ===, eql?, equal?
=> false # equality by value
=> false # gotcha?
irb> 1 == 1.0
=> true # generic equality
irb> 1 === ...
==, ===, eql?, equal?
=> false # equality by value
=> false # gotcha?
irb> 1 == 1.0
=> true # generic equality
irb> 1 === ...
==, ===, eql?, equal?
=> false # equality by value
=> false # gotcha?
irb> 1 == 1.0
=> true # generic equality
irb> 1 === ...
Object Ids & Fixnum
Object Ids & Fixnum
Fixnum * 2 + 1
irb> 23 * 2 + 1
=> 47
irb > 23.object_id
=> 47
Object Ids & Fixnum
Fixnum * 2 + 1
irb> 23 * 2 + 1
=> 47
irb > 23.object_id
=> 47
irb> (2**62 - 1).class
=> Fixnum
irb> (2...
http://www.flickr.com/photos/miscdebris/6748016253/sizes/o/
3 Pulls for the Jackpot
jackpot = lambda { |x, y, z|
(x == y) == (x == z)
}
# 3 pulls
pull = jackpot.curry[rand(5)]
2.time...
3 Pulls for the Jackpot
jackpot = lambda { |x, y, z|
(x == y) == (x == z)
}
# 3 pulls
pull = jackpot.curry[rand(5)]
2.time...
3 Pulls for the Jackpot
jackpot = lambda { |x, y, z|
(x == y) == (x == z)
}
# 3 pulls
pull = jackpot.curry[rand(5)]
2.time...
The curry recipe
• Return lambda till all parameters are passed.
• Evaluate the block if all parameters are passed.
pull =...
The curry recipe
• Return lambda till all parameters are passed.
• Evaluate the block if all parameters are passed.
pull =...
So! So you think you can tell…
Heaven from Hell
- Pink Floyd
So! So you think you can tell…
Protected from Private
Private methods
class Soldier
private
def ryan
puts "inside private ryan"
end
end
class Movie < Soldier
def name
ryan
end
...
Private methods
class Soldier
private
def ryan
puts "inside private ryan"
end
end
class Movie < Soldier
def name
ryan
end
...
Private methods
class Soldier
private
def ryan
puts "inside private ryan"
end
end
class Movie < Soldier
def name
ryan
end
...
class Base!
include Mongoid::Document!
end
The elusive include
class Base!
include Mongoid::Document!
end
The elusive include
Private method!
Instance method !
Defined the class Module
class Base!
include Mongoid::Document!
end
The elusive include
Protected methods
Protected methods
Protected methods
• Work with objects not classes.
Protected methods
• Work with objects not classes.
• Invoke a protected method on
another object in the same lineage
Protected methods
• Work with objects not classes.
• Invoke a protected method on
another object in the same lineage
What ...
class Autobot
def initialize(nick); @nick = nick; end
!
protected
attr_accessor :nick
end
!
prime = Autobot.new("Optimus P...
class Autobot
def initialize(nick); @nick = nick; end
!
protected
attr_accessor :nick
end
!
prime = Autobot.new("Optimus P...
class Autobot
def initialize(nick); @nick = nick; end
!
protected
attr_accessor :nick
end
!
prime = Autobot.new("Optimus P...
class Autobot
def fights(target)
p "I am #{self.nick}"
p "Kicking #{target.nick}'s ass"
end
protected
attr_accessor :nick
...
class Autobot
def fights(target)
p "I am #{self.nick}"
p "Kicking #{target.nick}'s ass"
end
protected
attr_accessor :nick
...
class Autobot
def fights(target)
p "I am #{self.nick}"
p "Kicking #{target.nick}'s ass"
end
protected
attr_accessor :nick
...
class Autobot
def fights(target)
p "I am #{self.nick}"
p "Kicking #{target.nick}'s ass"
end
protected
attr_accessor :nick
...
Keywords in Ruby?
Keywords - hmm…
class Serious
def true
false
end
def false
true
end
end
die = Serious.new
p "seriously!" if die.false
Keywords - hmm…
class Serious
def true
false
end
def false
true
end
end
die = Serious.new
p "seriously!" if die.false
Keywords - hmm…
class Serious
def true
false
end
def false
true
end
end
die = Serious.new
p "seriously!" if die.false
stac...
superlative
class Search!
def search!
p "Default Search algorithm"!
end!
end!
class KeywordSearch < Search !
def search(ke...
superlative
class Search!
def search!
p "Default Search algorithm"!
end!
end!
class KeywordSearch < Search !
def search(ke...
superlative
class Search!
def search!
p "Default Search algorithm"!
end!
end!
class KeywordSearch < Search !
def search(ke...
superlative
class Search!
def search!
p "Default Search algorithm"!
end!
end!
class KeywordSearch < Search !
def search(ke...
superlative
class Search!
def search!
p "Default Search algorithm"!
end!
end!
class KeywordSearch < Search !
def search(ke...
superlative
class Search!
def search!
p "Default Search algorithm"!
end!
end!
class KeywordSearch < Search !
def search(ke...
superlative
class Search!
def search!
p "Default Search algorithm"!
end!
end!
class KeywordSearch < Search !
def search(ke...
superlative
class Search!
def search!
p "Default Search algorithm"!
end!
end!
class KeywordSearch < Search !
def search(ke...
Module mixins are funny
module Superman!
def fly; p "Superman: It's a bird"; end!
end!
!
module Batman!
def fly; p "Batman...
Module mixins are funny
module Superman!
def fly; p "Superman: It's a bird"; end!
end!
!
module Batman!
def fly; p "Batman...
Module mixins are funny
class Tinyman!
include Superman!
include Batman!
include Ironman!
end!
!
Tinyman.new.fly
"Iroman: ...
Module mixins are funny
class Tinyman!
include Superman!
include Batman!
include Ironman!
end!
!
Tinyman.new.fly
"Iroman: ...
Module Inheritance?
module Superman!
def fly; p "Superman: It's a bird"; end!
end!
!
module Batman!
def fly; p "Batman: Fl...
Module Inheritance?
module Superman!
def fly; p "Superman: It's a bird"; end!
end!
!
module Batman!
def fly; p "Batman: Fl...
Module Inheritance?
module Superman!
def fly; p "Superman: It's a bird"; end!
end!
!
module Batman!
def fly; p "Batman: Fl...
Dynamic Inheritance!
class Tinyman!
include Superman!
include Batman!
include Ironman!
end
Dynamic Inheritance!
class Tinyman!
include Superman!
include Batman!
include Ironman!
end
class Tinyman!
include Superman!
include Ironman!
include Batman!
end
Dynamic Inheritance!
class Tinyman!
include Superman...
class Tinyman!
include Superman!
include Ironman!
include Batman!
end
Dynamic Inheritance!
class Tinyman!
include Superman...
Cherry pick from Modules
module Megatron!
def power!
p "Megatron's super strength"!
end!
!
def evil!
p 'Evil genius'!
end!...
Cherry pick from Modules
module Megatron!
def power!
p "Megatron's super strength"!
end!
!
def evil!
p 'Evil genius'!
end!...
class Hanuman!
include Megatron!
end
Hanuman.new.power!
# => "Megatron's super strength"!
Hanuman.new.evil !
# => "Evil ge...
class Hanuman!
include Megatron!
end
Hanuman.new.power!
# => "Megatron's super strength"!
Hanuman.new.evil !
# => "Evil ge...
Cherry pick from Modules
class Hanuman!
def power!
Megatron.instance_method(:power).!
bind(self).call!
end!
end
Cherry pick from Modules
class Hanuman!
def power!
Megatron.instance_method(:power).!
bind(self).call!
end!
end
Cherry pick from Modules
class Hanuman!
def power!
Megatron.instance_method(:power).!
bind(self).call!
end!
end
Hanuman.ne...
That’s all Folks!
@gautamrege
@joshsoftware
That’s all Folks!
@gautamrege
@joshsoftware
since 2007
ScotRuby - Dark side of ruby
Upcoming SlideShare
Loading in …5
×

ScotRuby - Dark side of ruby

1,075 views

Published on

Scottish Ruby Conference - "The Dark Side of Ruby"

Published in: Software, Technology, Education
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,075
On SlideShare
0
From Embeds
0
Number of Embeds
55
Actions
Shares
0
Downloads
5
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

ScotRuby - Dark side of ruby

  1. 1. The Dark Side of Ruby @gautamrege! @joshsoftware
  2. 2. What’s the talk about?
  3. 3. What’s the talk about? • Ruby is AWESOME but …
  4. 4. What’s the talk about? • Ruby is AWESOME but … • Nothing scary
  5. 5. What’s the talk about? • Ruby is AWESOME but … • Nothing scary really
  6. 6. What’s the talk about? • Ruby is AWESOME but … • Nothing scary • Weirdness and Gotcha’s really
  7. 7. What’s the talk about? • Ruby is AWESOME but … • Nothing scary • Weirdness and Gotcha’s Ah-ha! Moments really
  8. 8. Slides are Tagged
  9. 9. Slides are Tagged Beginner
  10. 10. Slides are Tagged Expert
  11. 11. (In)Famous Infinityhttp://www.flickr.com/photos/emdot/482622478/sizes/l/
  12. 12. (In)Famous Infinity
  13. 13. (In)Famous Infinity
  14. 14. (In)Famous Infinity $ irb> 1/0
  15. 15. (In)Famous Infinity $ irb> 1/0 => ZeroDivisionError: divided by 0
  16. 16. (In)Famous Infinity $ irb> 1/0 $ irb> 1.0/0 => ZeroDivisionError: divided by 0
  17. 17. (In)Famous Infinity $ irb> 1/0 $ irb> 1.0/0 => ZeroDivisionError: divided by 0 => Infinity
  18. 18. (In)Famous Infinity $ irb> 1/0 $ irb> 1.0/0 $ irb> Infinity => ZeroDivisionError: divided by 0 => Infinity
  19. 19. (In)Famous Infinity $ irb> 1/0 $ irb> 1.0/0 $ irb> Infinity => ZeroDivisionError: divided by 0 => Infinity => NameError: uninitialized constant Infinity
  20. 20. (In)Famous Infinity
  21. 21. (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;
  22. 22. (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
  23. 23. Base Jumping http://www.flickr.com/photos/shahdi/8035647153/sizes/l/
  24. 24. Base Conversions
  25. 25. Base Conversions
  26. 26. Base Conversions $ irb> 12345.to_s(8)
  27. 27. Base Conversions $ irb> 12345.to_s(8) => "30071" # => Octal
  28. 28. Base Conversions $ irb> 12345.to_s(8) $ irb> 12345.to_s(36) => "30071" # => Octal
  29. 29. Base Conversions $ irb> 12345.to_s(8) $ irb> 12345.to_s(36) => "30071" # => Octal => "9ix" # That is an actual number
  30. 30. 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
  31. 31. 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
  32. 32. Splat Expander
  33. 33. Splat Expander
  34. 34. Splat Expander Job = Struct.new(:name, :occupation) tom = Job.new("Tom", "Developer") name, occupation = *tom
  35. 35. Splat Expander Job = Struct.new(:name, :occupation) tom = Job.new("Tom", "Developer") name, occupation = *tom => ["Tom", "Developer"] => name # "Tom" => occupation # "Developer"
  36. 36. Splat Expander
  37. 37. Splat Expander Job = Struct.new(:name, :occupation) tom = Job.new(occupation: "Developer", name: "Tom") name, occupation = *tom
  38. 38. Splat Expander Job = Struct.new(:name, :occupation) tom = Job.new(occupation: "Developer", name: "Tom") name, occupation = *tom => name # {:occupation=>"Developer", :name=> "Tom"} => occupation # nil
  39. 39. Hashes and Arrays
  40. 40. Hashes and Arrays
  41. 41. Hashes and Arrays a=[1,2,3,4,5,6]! h=Hash[*a]
  42. 42. Hashes and Arrays a=[1,2,3,4,5,6]! h=Hash[*a] => {1=>2, 3=>4, 5=>6}
  43. 43. Hashes and Arrays a=[1,2,3,4,5,6]! h=Hash[*a] => {1=>2, 3=>4, 5=>6} [1,2,3] * 3
  44. 44. 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]
  45. 45. 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] * "%"
  46. 46. 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"
  47. 47. Calling out to Stabby
  48. 48. Calling out to Stabby blk = ->(f, *m, sl, l) do puts sl end
  49. 49. Calling out to Stabby blk = ->(f, *m, sl, l) do puts sl end blk.call(1, 2, 3, 4, 5, 6)
  50. 50. Calling out to Stabby blk = ->(f, *m, sl, l) do puts sl end blk.call(1, 2, 3, 4, 5, 6) => 5
  51. 51. blk.(1, 2, 3, 4, 5, 6) Calling out to Stabby blk = ->(f, *m, sl, l) do puts sl end blk.call(1, 2, 3, 4, 5, 6) => 5
  52. 52. blk.(1, 2, 3, 4, 5, 6) Calling out to Stabby blk = ->(f, *m, sl, l) do puts sl end blk.call(1, 2, 3, 4, 5, 6) => 5
  53. 53. blk.(1, 2, 3, 4, 5, 6) => 5 syntax sugar for call blk[1,2,3,4,5,6] Calling out to Stabby blk = ->(f, *m, sl, l) do puts sl end blk.call(1, 2, 3, 4, 5, 6) => 5
  54. 54. Syntax
  55. 55. Syntax def foo(a=1, b=1,opts={}) end
  56. 56. Syntax def foo(a: 1, b: 2) end keyword arguments
  57. 57. Syntax def foo(a: 1, b:, c: 2) end def foo(a: 1, b: 2) end keyword arguments
  58. 58. Syntax def foo(a: 1, b:, c: 2) end def foo(a: 1, b: 2) end keyword arguments
  59. 59. 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) end keyword arguments
  60. 60. Case Complexity
  61. 61. 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
  62. 62. 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
  63. 63. Behind every case is a === number = 9! case number ! when multiple_of(3) Proc.new {|p| p.modulo(3).zero?} === 9
  64. 64. Behind every case is a === number = 9! case number ! when multiple_of(3) Proc.new {|p| p.modulo(3).zero?} === 9
  65. 65. 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.
  66. 66. 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.
  67. 67. Override the === method to customise case evaluation.
  68. 68. ==, ===, eql?, equal? http://www.flickr.com/photos/gak/2418146934/sizes/o/
  69. 69. ==, ===, eql?, equal?
  70. 70. ==, ===, eql?, equal? irb> 1 == 1.0
  71. 71. ==, ===, eql?, equal? irb> 1 == 1.0 => true # generic equality
  72. 72. ==, ===, eql?, equal? irb> 1 == 1.0 => true # generic equality irb> 1 === 1.0
  73. 73. ==, ===, eql?, equal? irb> 1 == 1.0 => true # generic equality irb> 1 === 1.0 => true # case equality
  74. 74. ==, ===, eql?, equal? irb> 1 == 1.0 => true # generic equality irb> 1 === 1.0 => true # case equality irb> 1.eql? 1.0
  75. 75. ==, ===, eql?, equal? => false # equality by value irb> 1 == 1.0 => true # generic equality irb> 1 === 1.0 => true # case equality irb> 1.eql? 1.0
  76. 76. ==, ===, eql?, equal? => false # equality by value irb> 1 == 1.0 => true # generic equality irb> 1 === 1.0 => true # case equality irb> 1.eql? 1.0 irb> 1.equal? 1.0
  77. 77. ==, ===, eql?, equal? => false # equality by value irb> 1 == 1.0 => true # generic equality irb> 1 === 1.0 => true # case equality irb> 1.eql? 1.0 irb> 1.equal? 1.0 => false # object identity
  78. 78. ==, ===, eql?, equal? => false # equality by value irb> 1 == 1.0 => true # generic equality irb> 1 === 1.0 => true # case equality irb> 1.eql? 1.0 irb> 1.equal? 1.0 => false # object identity irb> 'a'.equal? 'a'
  79. 79. ==, ===, eql?, equal? => false # equality by value => false # gotcha? irb> 1 == 1.0 => true # generic equality irb> 1 === 1.0 => true # case equality irb> 1.eql? 1.0 irb> 1.equal? 1.0 => false # object identity irb> 'a'.equal? 'a'
  80. 80. ==, ===, eql?, equal? => false # equality by value => false # gotcha? irb> 1 == 1.0 => true # generic equality irb> 1 === 1.0 => true # case equality irb> 1.eql? 1.0 irb> 1.equal? 1.0 => false # object identity irb> 'a'.equal? 'a' irb> 1.equal? 1
  81. 81. ==, ===, eql?, equal? => false # equality by value => false # gotcha? irb> 1 == 1.0 => true # generic equality irb> 1 === 1.0 => true # case equality irb> 1.eql? 1.0 irb> 1.equal? 1.0 => false # object identity irb> 'a'.equal? 'a' => true # gotcha? irb> 1.equal? 1
  82. 82. Object Ids & Fixnum
  83. 83. Object Ids & Fixnum Fixnum * 2 + 1 irb> 23 * 2 + 1 => 47 irb > 23.object_id => 47
  84. 84. Object Ids & Fixnum Fixnum * 2 + 1 irb> 23 * 2 + 1 => 47 irb > 23.object_id => 47 irb> (2**62 - 1).class => Fixnum irb> (2**62).class => Bignum
  85. 85. http://www.flickr.com/photos/miscdebris/6748016253/sizes/o/
  86. 86. 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!"
  87. 87. 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!"
  88. 88. 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!"
  89. 89. 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
  90. 90. 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
  91. 91. So! So you think you can tell… Heaven from Hell - Pink Floyd
  92. 92. So! So you think you can tell… Protected from Private
  93. 93. Private methods class Soldier private def ryan puts "inside private ryan" end end class Movie < Soldier def name ryan end end
  94. 94. Private methods class Soldier private def ryan puts "inside private ryan" end end class Movie < Soldier def name ryan end end
  95. 95. Private methods class Soldier private def ryan puts "inside private ryan" end end class Movie < Soldier def name ryan end end Private Methods are inherited!
  96. 96. class Base! include Mongoid::Document! end The elusive include
  97. 97. class Base! include Mongoid::Document! end The elusive include
  98. 98. Private method! Instance method ! Defined the class Module class Base! include Mongoid::Document! end The elusive include
  99. 99. Protected methods
  100. 100. Protected methods
  101. 101. Protected methods • Work with objects not classes.
  102. 102. Protected methods • Work with objects not classes. • Invoke a protected method on another object in the same lineage
  103. 103. Protected methods • Work with objects not classes. • Invoke a protected method on another object in the same lineage What the …
  104. 104. class Autobot def initialize(nick); @nick = nick; end ! protected attr_accessor :nick end ! prime = Autobot.new("Optimus Prime") p prime.nick
  105. 105. class Autobot def initialize(nick); @nick = nick; end ! protected attr_accessor :nick end ! prime = Autobot.new("Optimus Prime") p prime.nick
  106. 106. 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)
  107. 107. 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
  108. 108. 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
  109. 109. 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"
  110. 110. 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"
  111. 111. Keywords in Ruby?
  112. 112. Keywords - hmm… class Serious def true false end def false true end end die = Serious.new p "seriously!" if die.false
  113. 113. Keywords - hmm… class Serious def true false end def false true end end die = Serious.new p "seriously!" if die.false
  114. 114. Keywords - hmm… class Serious def true false end def false true end end die = Serious.new p "seriously!" if die.false stack too deep?
  115. 115. superlative class Search! def search! p "Default Search algorithm"! end! end! class KeywordSearch < Search ! def search(keyword:)! super! end! end! KeywordSearch.new.search(keyword: "Ruby")
  116. 116. superlative class Search! def search! p "Default Search algorithm"! end! end! class KeywordSearch < Search ! def search(keyword:)! super! end! end! KeywordSearch.new.search(keyword: "Ruby")
  117. 117. superlative class Search! def search! p "Default Search algorithm"! end! end! class KeywordSearch < Search ! def search(keyword:)! super! end! end! KeywordSearch.new.search(keyword: "Ruby")
  118. 118. superlative class 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)
  119. 119. superlative class Search! def search! p "Default Search algorithm"! end! end! class KeywordSearch < Search ! def search(keyword:)! super()! end! end! KeywordSearch.new.search(keyword: "Ruby")
  120. 120. superlative class Search! def search! p "Default Search algorithm"! end! end! class KeywordSearch < Search ! def search(keyword:)! super()! end! end! KeywordSearch.new.search(keyword: "Ruby")
  121. 121. superlative class Search! def search! p "Default Search algorithm"! end! end! class KeywordSearch < Search ! def search(keyword:)! super()! end! end! KeywordSearch.new.search(keyword: "Ruby")
  122. 122. superlative class 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
  123. 123. Module mixins are funny 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; p "Iroman: That's flying!"; end! end
  124. 124. Module mixins are funny 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; p "Iroman: That's flying!"; end! end
  125. 125. Module mixins are funny class Tinyman! include Superman! include Batman! include Ironman! end! ! Tinyman.new.fly "Iroman: That's how you fly!"
  126. 126. Module mixins are funny class Tinyman! include Superman! include Batman! include Ironman! end! ! Tinyman.new.fly "Iroman: That's how you fly!"
  127. 127. 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
  128. 128. 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
  129. 129. 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!"
  130. 130. Dynamic Inheritance! class Tinyman! include Superman! include Batman! include Ironman! end
  131. 131. Dynamic Inheritance! class Tinyman! include Superman! include Batman! include Ironman! end
  132. 132. class Tinyman! include Superman! include Ironman! include Batman! end Dynamic Inheritance! class Tinyman! include Superman! include Batman! include Ironman! end
  133. 133. class Tinyman! include Superman! include Ironman! include Batman! end Dynamic Inheritance! class Tinyman! include Superman! include Batman! include Ironman! end
  134. 134. Cherry pick from Modules module Megatron! def power! p "Megatron's super strength"! end! ! def evil! p 'Evil genius'! end! end
  135. 135. Cherry pick from Modules module Megatron! def power! p "Megatron's super strength"! end! ! def evil! p 'Evil genius'! end! end
  136. 136. class Hanuman! include Megatron! end Hanuman.new.power! # => "Megatron's super strength"! Hanuman.new.evil ! # => "Evil genius" # Oh no! Cherry pick from Modules
  137. 137. class Hanuman! include Megatron! end Hanuman.new.power! # => "Megatron's super strength"! Hanuman.new.evil ! # => "Evil genius" # Oh no! Cherry pick from Modules
  138. 138. Cherry pick from Modules class Hanuman! def power! Megatron.instance_method(:power).! bind(self).call! end! end
  139. 139. Cherry pick from Modules class Hanuman! def power! Megatron.instance_method(:power).! bind(self).call! end! end
  140. 140. 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’...>
  141. 141. That’s all Folks! @gautamrege @joshsoftware
  142. 142. That’s all Folks! @gautamrege @joshsoftware since 2007

×