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

GCRC 2014 - The Dark Side of Ruby

May 10, 2015

Download

Technology

Gautam Rege

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!
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
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