SlideShare uma empresa Scribd logo
1 de 143
Baixar para ler offline
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: uninitialized constant
Infinity
(In)Famous Infinity
(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;
(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
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 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 an actual number
=> ArgumentError: invalid radix 64
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", "Developer"]
=> name # "Tom"
=> occupation # "Developer"
Splat Expander
Splat Expander
Job = Struct.new(:name, :occupation)
tom = Job.new(occupation: "Developer",
name: "Tom")
name, occupation = *tom
Splat Expander
Job = Struct.new(:name, :occupation)
tom = Job.new(occupation: "Developer",
name: "Tom")
name, occupation = *tom
=> name # {:occupation=>"Developer", :name=>
"Tom"}
=> occupation # nil
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%2%3"
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
end
blk.call(1, 2, 3, 4, 5, 6)
=> 5
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, b: 2)
end
keyword arguments
Case Complexity
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
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
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#=== is an alias to Proc#call.
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.
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 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 equality
irb> 1.eql? 1.0
irb> 1.equal? 1.0
==, ===, 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
==, ===, 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'
==, ===, 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'
==, ===, 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
==, ===, 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
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**62).class
=> Bignum
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.times { pull = pull.curry[rand(5)] }
!
p pull ? "Jackpot" : "Sucker!"
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!"
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!"
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
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
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
end
Private methods
class Soldier
private
def ryan
puts "inside private ryan"
end
end
class Movie < Soldier
def name
ryan
end
end
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!
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 the …
class Autobot
def initialize(nick); @nick = nick; end
!
protected
attr_accessor :nick
end
!
prime = Autobot.new("Optimus Prime")
p prime.nick
class Autobot
def initialize(nick); @nick = nick; end
!
protected
attr_accessor :nick
end
!
prime = Autobot.new("Optimus Prime")
p prime.nick
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)
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
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
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"
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"
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
stack too deep?
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")
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")
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")
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)
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")
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")
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")
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
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
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
Module mixins are funny
class Tinyman!
include Superman!
include Batman!
include Ironman!
end!
!
Tinyman.new.fly
"Iroman: That's how you fly!"
Module mixins are funny
class Tinyman!
include Superman!
include Batman!
include Ironman!
end!
!
Tinyman.new.fly
"Iroman: That's how you fly!"
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
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
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!"
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!
include Batman!
include Ironman!
end
class Tinyman!
include Superman!
include Ironman!
include Batman!
end
Dynamic Inheritance!
class Tinyman!
include Superman!
include Batman!
include Ironman!
end
Cherry pick from Modules
module Megatron!
def power!
p "Megatron's super strength"!
end!
!
def evil!
p 'Evil genius'!
end!
end
Cherry pick from Modules
module Megatron!
def power!
p "Megatron's super strength"!
end!
!
def evil!
p 'Evil genius'!
end!
end
class Hanuman!
include Megatron!
end
Hanuman.new.power!
# => "Megatron's super strength"!
Hanuman.new.evil !
# => "Evil genius" # Oh no!
Cherry pick from Modules
class Hanuman!
include Megatron!
end
Hanuman.new.power!
# => "Megatron's super strength"!
Hanuman.new.evil !
# => "Evil genius" # Oh no!
Cherry pick from Modules
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.new.power
# => "Megatron's super strength"
Hanuman.new.evil
# => undefined method `evil’...>
That’s all Folks!
@gautamrege
@joshsoftware
That’s all Folks!
@gautamrege
@joshsoftware
since 2007

Mais conteúdo relacionado

Mais procurados

Perl.Hacks.On.Vim Perlchina
Perl.Hacks.On.Vim PerlchinaPerl.Hacks.On.Vim Perlchina
Perl.Hacks.On.Vim PerlchinaLin Yo-An
 
Good Evils In Perl
Good Evils In PerlGood Evils In Perl
Good Evils In PerlKang-min Liu
 
Refactor like a boss
Refactor like a bossRefactor like a boss
Refactor like a bossgsterndale
 
Rails for PHP Developers
Rails for PHP DevelopersRails for PHP Developers
Rails for PHP DevelopersRobert Dempsey
 
Perl.Hacks.On.Vim Perlchina
Perl.Hacks.On.Vim PerlchinaPerl.Hacks.On.Vim Perlchina
Perl.Hacks.On.Vim Perlchinaguestcf9240
 
Exhibition of Atrocity
Exhibition of AtrocityExhibition of Atrocity
Exhibition of AtrocityMichael Pirnat
 
Extreme Swift
Extreme SwiftExtreme Swift
Extreme SwiftMovel
 
Python for High School Programmers
Python for High School ProgrammersPython for High School Programmers
Python for High School ProgrammersSiva Arunachalam
 
Class 6: Lists & dictionaries
Class 6: Lists & dictionariesClass 6: Lists & dictionaries
Class 6: Lists & dictionariesMarc Gouw
 
Slides chapter3part1 ruby-forjavaprogrammers
Slides chapter3part1 ruby-forjavaprogrammersSlides chapter3part1 ruby-forjavaprogrammers
Slides chapter3part1 ruby-forjavaprogrammersGiovanni924
 
Use cases in the code with AOP
Use cases in the code with AOPUse cases in the code with AOP
Use cases in the code with AOPAndrzej Krzywda
 
Investigating Python Wats
Investigating Python WatsInvestigating Python Wats
Investigating Python WatsAmy Hanlon
 
Python Fundamentals - Basic
Python Fundamentals - BasicPython Fundamentals - Basic
Python Fundamentals - BasicWei-Yuan Chang
 
Real world gobbledygook
Real world gobbledygookReal world gobbledygook
Real world gobbledygookPawel Szulc
 
NUS iOS Swift Talk
NUS iOS Swift TalkNUS iOS Swift Talk
NUS iOS Swift TalkGabriel Lim
 
All Objects are created .equal?
All Objects are created .equal?All Objects are created .equal?
All Objects are created .equal?gsterndale
 
Round PEG, Round Hole - Parsing Functionally
Round PEG, Round Hole - Parsing FunctionallyRound PEG, Round Hole - Parsing Functionally
Round PEG, Round Hole - Parsing FunctionallySean Cribbs
 
Slaying the Dragon: Implementing a Programming Language in Ruby
Slaying the Dragon: Implementing a Programming Language in RubySlaying the Dragon: Implementing a Programming Language in Ruby
Slaying the Dragon: Implementing a Programming Language in RubyJason Yeo Jie Shun
 
Perl Xpath Lightning Talk
Perl Xpath Lightning TalkPerl Xpath Lightning Talk
Perl Xpath Lightning Talkddn123456
 

Mais procurados (20)

Perl.Hacks.On.Vim Perlchina
Perl.Hacks.On.Vim PerlchinaPerl.Hacks.On.Vim Perlchina
Perl.Hacks.On.Vim Perlchina
 
Good Evils In Perl
Good Evils In PerlGood Evils In Perl
Good Evils In Perl
 
Refactor like a boss
Refactor like a bossRefactor like a boss
Refactor like a boss
 
Rails for PHP Developers
Rails for PHP DevelopersRails for PHP Developers
Rails for PHP Developers
 
Perl.Hacks.On.Vim Perlchina
Perl.Hacks.On.Vim PerlchinaPerl.Hacks.On.Vim Perlchina
Perl.Hacks.On.Vim Perlchina
 
Exhibition of Atrocity
Exhibition of AtrocityExhibition of Atrocity
Exhibition of Atrocity
 
Extreme Swift
Extreme SwiftExtreme Swift
Extreme Swift
 
Python for High School Programmers
Python for High School ProgrammersPython for High School Programmers
Python for High School Programmers
 
Class 6: Lists & dictionaries
Class 6: Lists & dictionariesClass 6: Lists & dictionaries
Class 6: Lists & dictionaries
 
Slides chapter3part1 ruby-forjavaprogrammers
Slides chapter3part1 ruby-forjavaprogrammersSlides chapter3part1 ruby-forjavaprogrammers
Slides chapter3part1 ruby-forjavaprogrammers
 
Use cases in the code with AOP
Use cases in the code with AOPUse cases in the code with AOP
Use cases in the code with AOP
 
Investigating Python Wats
Investigating Python WatsInvestigating Python Wats
Investigating Python Wats
 
Python Fundamentals - Basic
Python Fundamentals - BasicPython Fundamentals - Basic
Python Fundamentals - Basic
 
Begin with Python
Begin with PythonBegin with Python
Begin with Python
 
Real world gobbledygook
Real world gobbledygookReal world gobbledygook
Real world gobbledygook
 
NUS iOS Swift Talk
NUS iOS Swift TalkNUS iOS Swift Talk
NUS iOS Swift Talk
 
All Objects are created .equal?
All Objects are created .equal?All Objects are created .equal?
All Objects are created .equal?
 
Round PEG, Round Hole - Parsing Functionally
Round PEG, Round Hole - Parsing FunctionallyRound PEG, Round Hole - Parsing Functionally
Round PEG, Round Hole - Parsing Functionally
 
Slaying the Dragon: Implementing a Programming Language in Ruby
Slaying the Dragon: Implementing a Programming Language in RubySlaying the Dragon: Implementing a Programming Language in Ruby
Slaying the Dragon: Implementing a Programming Language in Ruby
 
Perl Xpath Lightning Talk
Perl Xpath Lightning TalkPerl Xpath Lightning Talk
Perl Xpath Lightning Talk
 

Semelhante a ScotRuby - Dark side of ruby

Ruby 程式語言入門導覽
Ruby 程式語言入門導覽Ruby 程式語言入門導覽
Ruby 程式語言入門導覽Wen-Tien Chang
 
Ruby 入門 第一次就上手
Ruby 入門 第一次就上手Ruby 入門 第一次就上手
Ruby 入門 第一次就上手Wen-Tien Chang
 
Writing Apps the Google-y Way (Brisbane)
Writing Apps the Google-y Way (Brisbane)Writing Apps the Google-y Way (Brisbane)
Writing Apps the Google-y Way (Brisbane)Pamela Fox
 
Perl 6 in Context
Perl 6 in ContextPerl 6 in Context
Perl 6 in Contextlichtkind
 
Invertible-syntax 入門
Invertible-syntax 入門Invertible-syntax 入門
Invertible-syntax 入門Hiromi Ishii
 
Programming Language Swift Overview
Programming Language Swift OverviewProgramming Language Swift Overview
Programming Language Swift OverviewKaz Yoshikawa
 
GCRC 2014 - The Dark Side of Ruby
GCRC 2014 - The Dark Side of RubyGCRC 2014 - The Dark Side of Ruby
GCRC 2014 - The Dark Side of RubyGautam Rege
 
Writing Apps the Google-y Way
Writing Apps the Google-y WayWriting Apps the Google-y Way
Writing Apps the Google-y WayPamela Fox
 
Ruby 程式語言簡介
Ruby 程式語言簡介Ruby 程式語言簡介
Ruby 程式語言簡介Wen-Tien Chang
 
Threequals - Case Equality in Ruby
Threequals - Case Equality in RubyThreequals - Case Equality in Ruby
Threequals - Case Equality in RubyLouis Scoras
 
Functional Programming with Groovy
Functional Programming with GroovyFunctional Programming with Groovy
Functional Programming with GroovyArturo Herrero
 
Front end fundamentals session 1: javascript core
Front end fundamentals session 1: javascript coreFront end fundamentals session 1: javascript core
Front end fundamentals session 1: javascript coreWeb Zhao
 
Ruby 程式語言綜覽簡介
Ruby 程式語言綜覽簡介Ruby 程式語言綜覽簡介
Ruby 程式語言綜覽簡介Wen-Tien Chang
 
A Taste of Python - Devdays Toronto 2009
A Taste of Python - Devdays Toronto 2009A Taste of Python - Devdays Toronto 2009
A Taste of Python - Devdays Toronto 2009Jordan Baker
 
Feel of Kotlin (Berlin JUG 16 Apr 2015)
Feel of Kotlin (Berlin JUG 16 Apr 2015)Feel of Kotlin (Berlin JUG 16 Apr 2015)
Feel of Kotlin (Berlin JUG 16 Apr 2015)intelliyole
 
Is Haskell an acceptable Perl?
Is Haskell an acceptable Perl?Is Haskell an acceptable Perl?
Is Haskell an acceptable Perl?osfameron
 
Idioms in swift 2016 05c
Idioms in swift 2016 05cIdioms in swift 2016 05c
Idioms in swift 2016 05cKaz Yoshikawa
 
A Lifecycle Of Code Under Test by Robert Fornal
A Lifecycle Of Code Under Test by Robert FornalA Lifecycle Of Code Under Test by Robert Fornal
A Lifecycle Of Code Under Test by Robert FornalQA or the Highway
 

Semelhante a ScotRuby - Dark side of ruby (20)

Ruby 程式語言入門導覽
Ruby 程式語言入門導覽Ruby 程式語言入門導覽
Ruby 程式語言入門導覽
 
Ruby 入門 第一次就上手
Ruby 入門 第一次就上手Ruby 入門 第一次就上手
Ruby 入門 第一次就上手
 
Writing Apps the Google-y Way (Brisbane)
Writing Apps the Google-y Way (Brisbane)Writing Apps the Google-y Way (Brisbane)
Writing Apps the Google-y Way (Brisbane)
 
Perl 6 in Context
Perl 6 in ContextPerl 6 in Context
Perl 6 in Context
 
An introduction to Ruby
An introduction to RubyAn introduction to Ruby
An introduction to Ruby
 
Invertible-syntax 入門
Invertible-syntax 入門Invertible-syntax 入門
Invertible-syntax 入門
 
Programming Language Swift Overview
Programming Language Swift OverviewProgramming Language Swift Overview
Programming Language Swift Overview
 
GCRC 2014 - The Dark Side of Ruby
GCRC 2014 - The Dark Side of RubyGCRC 2014 - The Dark Side of Ruby
GCRC 2014 - The Dark Side of Ruby
 
Writing Apps the Google-y Way
Writing Apps the Google-y WayWriting Apps the Google-y Way
Writing Apps the Google-y Way
 
Ruby 程式語言簡介
Ruby 程式語言簡介Ruby 程式語言簡介
Ruby 程式語言簡介
 
Threequals - Case Equality in Ruby
Threequals - Case Equality in RubyThreequals - Case Equality in Ruby
Threequals - Case Equality in Ruby
 
Functional Programming with Groovy
Functional Programming with GroovyFunctional Programming with Groovy
Functional Programming with Groovy
 
Front end fundamentals session 1: javascript core
Front end fundamentals session 1: javascript coreFront end fundamentals session 1: javascript core
Front end fundamentals session 1: javascript core
 
Ruby 程式語言綜覽簡介
Ruby 程式語言綜覽簡介Ruby 程式語言綜覽簡介
Ruby 程式語言綜覽簡介
 
A Taste of Python - Devdays Toronto 2009
A Taste of Python - Devdays Toronto 2009A Taste of Python - Devdays Toronto 2009
A Taste of Python - Devdays Toronto 2009
 
Feel of Kotlin (Berlin JUG 16 Apr 2015)
Feel of Kotlin (Berlin JUG 16 Apr 2015)Feel of Kotlin (Berlin JUG 16 Apr 2015)
Feel of Kotlin (Berlin JUG 16 Apr 2015)
 
Is Haskell an acceptable Perl?
Is Haskell an acceptable Perl?Is Haskell an acceptable Perl?
Is Haskell an acceptable Perl?
 
Idioms in swift 2016 05c
Idioms in swift 2016 05cIdioms in swift 2016 05c
Idioms in swift 2016 05c
 
Python 101 1
Python 101   1Python 101   1
Python 101 1
 
A Lifecycle Of Code Under Test by Robert Fornal
A Lifecycle Of Code Under Test by Robert FornalA Lifecycle Of Code Under Test by Robert Fornal
A Lifecycle Of Code Under Test by Robert Fornal
 

Mais de Gautam Rege

RubyConf India 2019 - Confessions of a rubypreneur
RubyConf India 2019 - Confessions of a rubypreneurRubyConf India 2019 - Confessions of a rubypreneur
RubyConf India 2019 - Confessions of a rubypreneurGautam Rege
 
GoFFIng around with Ruby #RubyConfPH
GoFFIng around with Ruby #RubyConfPHGoFFIng around with Ruby #RubyConfPH
GoFFIng around with Ruby #RubyConfPHGautam Rege
 
Agile india 2017 - Rewarding OpenSource with $$$
Agile india 2017 - Rewarding OpenSource with $$$Agile india 2017 - Rewarding OpenSource with $$$
Agile india 2017 - Rewarding OpenSource with $$$Gautam Rege
 
WIDS - Gamifying Open Source
WIDS - Gamifying Open SourceWIDS - Gamifying Open Source
WIDS - Gamifying Open SourceGautam Rege
 
Gamifying Open Source
Gamifying Open SourceGamifying Open Source
Gamifying Open SourceGautam Rege
 
Affordable Smart Housing - The new revolution
Affordable Smart Housing - The new revolutionAffordable Smart Housing - The new revolution
Affordable Smart Housing - The new revolutionGautam Rege
 
WebSummit 2015 - Gopher it
WebSummit 2015 - Gopher itWebSummit 2015 - Gopher it
WebSummit 2015 - Gopher itGautam Rege
 
Dont test your code
Dont test your codeDont test your code
Dont test your codeGautam Rege
 
Art of speaking at tech conferences
Art of speaking at tech conferencesArt of speaking at tech conferences
Art of speaking at tech conferencesGautam Rege
 
RubyConf Portugal 2014 - Why ruby must go!
RubyConf Portugal 2014 - Why ruby must go!RubyConf Portugal 2014 - Why ruby must go!
RubyConf Portugal 2014 - Why ruby must go!Gautam Rege
 
Ruby and rails - Advanced Training (Cybage)
Ruby and rails - Advanced Training (Cybage)Ruby and rails - Advanced Training (Cybage)
Ruby and rails - Advanced Training (Cybage)Gautam Rege
 
Rails Vs CakePHP
Rails Vs CakePHPRails Vs CakePHP
Rails Vs CakePHPGautam Rege
 

Mais de Gautam Rege (13)

RubyConf India 2019 - Confessions of a rubypreneur
RubyConf India 2019 - Confessions of a rubypreneurRubyConf India 2019 - Confessions of a rubypreneur
RubyConf India 2019 - Confessions of a rubypreneur
 
GoFFIng around with Ruby #RubyConfPH
GoFFIng around with Ruby #RubyConfPHGoFFIng around with Ruby #RubyConfPH
GoFFIng around with Ruby #RubyConfPH
 
Agile india 2017 - Rewarding OpenSource with $$$
Agile india 2017 - Rewarding OpenSource with $$$Agile india 2017 - Rewarding OpenSource with $$$
Agile india 2017 - Rewarding OpenSource with $$$
 
WIDS - Gamifying Open Source
WIDS - Gamifying Open SourceWIDS - Gamifying Open Source
WIDS - Gamifying Open Source
 
Gamifying Open Source
Gamifying Open SourceGamifying Open Source
Gamifying Open Source
 
Affordable Smart Housing - The new revolution
Affordable Smart Housing - The new revolutionAffordable Smart Housing - The new revolution
Affordable Smart Housing - The new revolution
 
WebSummit 2015 - Gopher it
WebSummit 2015 - Gopher itWebSummit 2015 - Gopher it
WebSummit 2015 - Gopher it
 
Dont test your code
Dont test your codeDont test your code
Dont test your code
 
Art of speaking at tech conferences
Art of speaking at tech conferencesArt of speaking at tech conferences
Art of speaking at tech conferences
 
RubyConf Portugal 2014 - Why ruby must go!
RubyConf Portugal 2014 - Why ruby must go!RubyConf Portugal 2014 - Why ruby must go!
RubyConf Portugal 2014 - Why ruby must go!
 
Ruby and rails - Advanced Training (Cybage)
Ruby and rails - Advanced Training (Cybage)Ruby and rails - Advanced Training (Cybage)
Ruby and rails - Advanced Training (Cybage)
 
Rails Vs CakePHP
Rails Vs CakePHPRails Vs CakePHP
Rails Vs CakePHP
 
Ruby On Rails
Ruby On RailsRuby On Rails
Ruby On Rails
 

Último

Mastering Project Planning with Microsoft Project 2016.pptx
Mastering Project Planning with Microsoft Project 2016.pptxMastering Project Planning with Microsoft Project 2016.pptx
Mastering Project Planning with Microsoft Project 2016.pptxAS Design & AST.
 
Advantages of Cargo Cloud Solutions.pptx
Advantages of Cargo Cloud Solutions.pptxAdvantages of Cargo Cloud Solutions.pptx
Advantages of Cargo Cloud Solutions.pptxRTS corp
 
2024-04-09 - From Complexity to Clarity - AWS Summit AMS.pdf
2024-04-09 - From Complexity to Clarity - AWS Summit AMS.pdf2024-04-09 - From Complexity to Clarity - AWS Summit AMS.pdf
2024-04-09 - From Complexity to Clarity - AWS Summit AMS.pdfAndrey Devyatkin
 
Effectively Troubleshoot 9 Types of OutOfMemoryError
Effectively Troubleshoot 9 Types of OutOfMemoryErrorEffectively Troubleshoot 9 Types of OutOfMemoryError
Effectively Troubleshoot 9 Types of OutOfMemoryErrorTier1 app
 
JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...
JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...
JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...Bert Jan Schrijver
 
Pros and Cons of Selenium In Automation Testing_ A Comprehensive Assessment.pdf
Pros and Cons of Selenium In Automation Testing_ A Comprehensive Assessment.pdfPros and Cons of Selenium In Automation Testing_ A Comprehensive Assessment.pdf
Pros and Cons of Selenium In Automation Testing_ A Comprehensive Assessment.pdfkalichargn70th171
 
Zer0con 2024 final share short version.pdf
Zer0con 2024 final share short version.pdfZer0con 2024 final share short version.pdf
Zer0con 2024 final share short version.pdfmaor17
 
[ CNCF Q1 2024 ] Intro to Continuous Profiling and Grafana Pyroscope.pdf
[ CNCF Q1 2024 ] Intro to Continuous Profiling and Grafana Pyroscope.pdf[ CNCF Q1 2024 ] Intro to Continuous Profiling and Grafana Pyroscope.pdf
[ CNCF Q1 2024 ] Intro to Continuous Profiling and Grafana Pyroscope.pdfSteve Caron
 
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...OnePlan Solutions
 
Amazon Bedrock in Action - presentation of the Bedrock's capabilities
Amazon Bedrock in Action - presentation of the Bedrock's capabilitiesAmazon Bedrock in Action - presentation of the Bedrock's capabilities
Amazon Bedrock in Action - presentation of the Bedrock's capabilitiesKrzysztofKkol1
 
OpenChain AI Study Group - Europe and Asia Recap - 2024-04-11 - Full Recording
OpenChain AI Study Group - Europe and Asia Recap - 2024-04-11 - Full RecordingOpenChain AI Study Group - Europe and Asia Recap - 2024-04-11 - Full Recording
OpenChain AI Study Group - Europe and Asia Recap - 2024-04-11 - Full RecordingShane Coughlan
 
The Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptx
The Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptxThe Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptx
The Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptxRTS corp
 
Osi security architecture in network.pptx
Osi security architecture in network.pptxOsi security architecture in network.pptx
Osi security architecture in network.pptxVinzoCenzo
 
Introduction to Firebase Workshop Slides
Introduction to Firebase Workshop SlidesIntroduction to Firebase Workshop Slides
Introduction to Firebase Workshop Slidesvaideheekore1
 
Best Angular 17 Classroom & Online training - Naresh IT
Best Angular 17 Classroom & Online training - Naresh ITBest Angular 17 Classroom & Online training - Naresh IT
Best Angular 17 Classroom & Online training - Naresh ITmanoharjgpsolutions
 
GraphSummit Madrid - Product Vision and Roadmap - Luis Salvador Neo4j
GraphSummit Madrid - Product Vision and Roadmap - Luis Salvador Neo4jGraphSummit Madrid - Product Vision and Roadmap - Luis Salvador Neo4j
GraphSummit Madrid - Product Vision and Roadmap - Luis Salvador Neo4jNeo4j
 
Keeping your build tool updated in a multi repository world
Keeping your build tool updated in a multi repository worldKeeping your build tool updated in a multi repository world
Keeping your build tool updated in a multi repository worldRoberto Pérez Alcolea
 
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...OnePlan Solutions
 
2024 DevNexus Patterns for Resiliency: Shuffle shards
2024 DevNexus Patterns for Resiliency: Shuffle shards2024 DevNexus Patterns for Resiliency: Shuffle shards
2024 DevNexus Patterns for Resiliency: Shuffle shardsChristopher Curtin
 
Enhancing Supply Chain Visibility with Cargo Cloud Solutions.pdf
Enhancing Supply Chain Visibility with Cargo Cloud Solutions.pdfEnhancing Supply Chain Visibility with Cargo Cloud Solutions.pdf
Enhancing Supply Chain Visibility with Cargo Cloud Solutions.pdfRTS corp
 

Último (20)

Mastering Project Planning with Microsoft Project 2016.pptx
Mastering Project Planning with Microsoft Project 2016.pptxMastering Project Planning with Microsoft Project 2016.pptx
Mastering Project Planning with Microsoft Project 2016.pptx
 
Advantages of Cargo Cloud Solutions.pptx
Advantages of Cargo Cloud Solutions.pptxAdvantages of Cargo Cloud Solutions.pptx
Advantages of Cargo Cloud Solutions.pptx
 
2024-04-09 - From Complexity to Clarity - AWS Summit AMS.pdf
2024-04-09 - From Complexity to Clarity - AWS Summit AMS.pdf2024-04-09 - From Complexity to Clarity - AWS Summit AMS.pdf
2024-04-09 - From Complexity to Clarity - AWS Summit AMS.pdf
 
Effectively Troubleshoot 9 Types of OutOfMemoryError
Effectively Troubleshoot 9 Types of OutOfMemoryErrorEffectively Troubleshoot 9 Types of OutOfMemoryError
Effectively Troubleshoot 9 Types of OutOfMemoryError
 
JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...
JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...
JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...
 
Pros and Cons of Selenium In Automation Testing_ A Comprehensive Assessment.pdf
Pros and Cons of Selenium In Automation Testing_ A Comprehensive Assessment.pdfPros and Cons of Selenium In Automation Testing_ A Comprehensive Assessment.pdf
Pros and Cons of Selenium In Automation Testing_ A Comprehensive Assessment.pdf
 
Zer0con 2024 final share short version.pdf
Zer0con 2024 final share short version.pdfZer0con 2024 final share short version.pdf
Zer0con 2024 final share short version.pdf
 
[ CNCF Q1 2024 ] Intro to Continuous Profiling and Grafana Pyroscope.pdf
[ CNCF Q1 2024 ] Intro to Continuous Profiling and Grafana Pyroscope.pdf[ CNCF Q1 2024 ] Intro to Continuous Profiling and Grafana Pyroscope.pdf
[ CNCF Q1 2024 ] Intro to Continuous Profiling and Grafana Pyroscope.pdf
 
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...
 
Amazon Bedrock in Action - presentation of the Bedrock's capabilities
Amazon Bedrock in Action - presentation of the Bedrock's capabilitiesAmazon Bedrock in Action - presentation of the Bedrock's capabilities
Amazon Bedrock in Action - presentation of the Bedrock's capabilities
 
OpenChain AI Study Group - Europe and Asia Recap - 2024-04-11 - Full Recording
OpenChain AI Study Group - Europe and Asia Recap - 2024-04-11 - Full RecordingOpenChain AI Study Group - Europe and Asia Recap - 2024-04-11 - Full Recording
OpenChain AI Study Group - Europe and Asia Recap - 2024-04-11 - Full Recording
 
The Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptx
The Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptxThe Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptx
The Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptx
 
Osi security architecture in network.pptx
Osi security architecture in network.pptxOsi security architecture in network.pptx
Osi security architecture in network.pptx
 
Introduction to Firebase Workshop Slides
Introduction to Firebase Workshop SlidesIntroduction to Firebase Workshop Slides
Introduction to Firebase Workshop Slides
 
Best Angular 17 Classroom & Online training - Naresh IT
Best Angular 17 Classroom & Online training - Naresh ITBest Angular 17 Classroom & Online training - Naresh IT
Best Angular 17 Classroom & Online training - Naresh IT
 
GraphSummit Madrid - Product Vision and Roadmap - Luis Salvador Neo4j
GraphSummit Madrid - Product Vision and Roadmap - Luis Salvador Neo4jGraphSummit Madrid - Product Vision and Roadmap - Luis Salvador Neo4j
GraphSummit Madrid - Product Vision and Roadmap - Luis Salvador Neo4j
 
Keeping your build tool updated in a multi repository world
Keeping your build tool updated in a multi repository worldKeeping your build tool updated in a multi repository world
Keeping your build tool updated in a multi repository world
 
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...
 
2024 DevNexus Patterns for Resiliency: Shuffle shards
2024 DevNexus Patterns for Resiliency: Shuffle shards2024 DevNexus Patterns for Resiliency: Shuffle shards
2024 DevNexus Patterns for Resiliency: Shuffle shards
 
Enhancing Supply Chain Visibility with Cargo Cloud Solutions.pdf
Enhancing Supply Chain Visibility with Cargo Cloud Solutions.pdfEnhancing Supply Chain Visibility with Cargo Cloud Solutions.pdf
Enhancing Supply Chain Visibility with Cargo Cloud Solutions.pdf
 

ScotRuby - Dark side of ruby