Casting
Casting to a Float
"123.50".to_f #=> 123.5
Float("123.50") #=> 123.5
Casting to a String
123.5.to_s #=> "123.5"
String(123.5) #=> "123.5"
sprintf("%s", 123.5) #=> "123.5"
"%s" % 123.5 #=> "123.5"
"%d" % 123.5 #=> "123"
"%.2f" % 123.5 #=> "123.50"
Casting to an Integer
"123.50".to_i #=> 123
Integer("123.50") #=> 123
Floats and Integers
1.0 / 2 #=> 0.5
1.to_f / 2 #=> 0.5
1 / Float(2) #=> 0.5
1.fdiv 2 # => 0.5
Operators
Operator Precedence and Methods
class Foo
def **(x)
puts "Raising to the power of #{x}"
end
def <<(y)
puts "Shifting left by #{y}"
end
def !
puts "Boolean negation"
end
end
Foo.new ** 2 Foo.new << 3 !Foo.new
class Foo
def [](x)
puts "Looking up item #{x}"
end
def []=(x,y)
puts "Setting item #{x} to #{y}"
end
end
f = Foo.new
f[:cats] = 42 #=> "Setting item cats to 42"
f[17] #=> "Looking up item 17"
class Foo
def -@
puts "unary minus" end
def +@
puts "unary plus"
end
end
f = Foo.new
+f #=> "unary plus"
-f #=> "unary minus"
class Foo
def ==(x)
puts "checking for EQUALITY with #{x}, returning false"
false
end
end
f = Foo.new
x = (f == 42) #=> "checking for EQUALITY with 42, returning false"
puts x #=> "false"
x = (f != 42) #=> "checking for EQUALITY with 42, returning false"
puts x #=> "true"
class Foo
def !=(x)
puts "Checking for INequality with #{x}"
end
end
f != 42 #=> "checking for INequality with 42"
Case equality operator (===)
(1..5) === 3 # => true
(1..5) === 6 # => false
Integer === 42 # => true
Integer === 'fourtytwo'# => false
/ell/ === 'Hello' # => true
/ell/ === 'Foobar'# => false
Safe Navigation Operator
# Bad
if house && house.address && house.address.street_name
house.address.street_name
end
# Good
if house&.address&.street_name
house.address.street_name
end
Assignment Operators
x, y = 3, 9
x, y = y, x
puts "x is #{x}, y is #{y}" # => x is 9, y is 3
Comparison Operators
Variable Scope and Visibility
Class Variables
class Dinosaur
@@classification = "Like a Reptile, but like a bird"
def self.classification
@@classification
end
def classification
@@classification
end
end
dino = Dinosaur.new
dino.classification
# => "Like a Reptile, but like a bird"
Dinosaur.classification
# => "Like a Reptile, but like a bird"
class TRex < Dinosaur
@@classification = "Big teeth bird!"
end
TRex.classification
# => "Big teeth bird!"
Dinosaur.classification
# => "Big teeth bird!"
module SomethingStrange
@@classification = "Something Strange"
end
class DuckDinosaur < Dinosaur
include SomethingStrange
end
DuckDinosaur.class_variables # => [:@@classification]
SomethingStrange.class_variables # => [:@@classification]
DuckDinosaur.classification # => "Big teeth bird!"
Local Variables
def some_method
method_scope_var = "hi there"
p method_scope_var
end
some_method
# hi there
# => hi there
method_scope_var
# NameError: undefined local variable or method `method_scope_var'
Arrays
Create Array of Strings
array = %w(one two three four)
array = ['one', 'two', 'three', 'four']
Create Array with Array::new
Array.new 3 #=> [nil, nil, nil]
Array.new 3, :x #=> [:x, :x, :x]
Array.new(3) { |i| i.to_s } #=> ["0", "1", "2"]
b = Array.new(3) { "X" }
b[1].replace "C"
Create Array of Symbols
array = %i(one two three four)
Manipulating Array Elements
[1, 2, 3] << 4
# => [1, 2, 3, 4]
[1, 2, 3].push(4) # => [1, 2, 3, 4]
[1, 2, 3].unshift(4) # => [4, 1, 2, 3]
[1, 2, 3] << [4, 5]
# => [1, 2, 3, [4, 5]]
array = [1, 2, 3, 4] array.pop
# => 4
array
# => [1, 2, 3]
array = [1, 2, 3, 4] array.shift
# => 1
array
# => [2, 3, 4]
array = [1, 2, 3, 4] array.delete(1)
# => 1
array
# => [2, 3, 4]
array = [1,2,3,4,5,6]
array.delete_at(2) // delete from index 2 # => 3
array
# => [1,2,4,5,6]
array = [1, 2, 2, 2, 3]
array - [2]
# => [1, 3] # removed all the 2s array - [2, 3, 4]
# => [1] # the 4 did nothing
[1, 2, 3] + [4, 5, 6]
# => [1, 2, 3, 4, 5, 6]
[1, 2, 3].concat([4, 5, 6]) # => [1, 2, 3, 4, 5, 6]
[1, 2, 3, 4, 5, 6] - [2, 3] # => [1, 4, 5, 6]
[1, 2, 3] | [2, 3, 4] # => [1, 2, 3, 4]
[1, 2, 3] & [3, 4] # => [3]
[1, 2, 3] * 2
# => [1, 2, 3, 1, 2, 3]
Accessing elements
%w(a b c)[0] # => 'a'
%w(a b c)[1] # => 'b'
%w(a b c d)[1..2] # => ['b', 'c'] (indices from 1 to 2, including the 2)
%w(a b c d)[1...2] # => ['b'] (indices from 1 to 2, excluding the 2)
%w(a b c)[-1] # => 'c'
%w(a b c)[-2] # => 'b'
%w(a b c d e)[1...-1] # => ['b', 'c', 'd']
[1, 2, 3, 4].first # => 1
[1, 2, 3, 4].first(2) # => [1, 2]
[1, 2, 3, 4].last # => 4
[1, 2, 3, 4].last(2) # => [3, 4]
[1, 2, 3, 4].sample # => 3
[1, 2, 3, 4].sample # => 1
[1, 2, 3, 4].sample(2) # => [2, 1]
[1, 2, 3, 4].sample(2) # => [3, 4]
Creating an Array with the literal constructor [ ]
array = [1, 2, 3, 4]
array = [1, 'b', nil, [3, 4]]
Decomposition
arr = [1, 2, 3] # ---
a = arr[0]
b = arr[1]
c = arr[2]
# --- or, the same
a, b, c = arr
a, *b = arr # a = 1; b = [2, 3]
a, *b, c = arr # a = 1; b = [2]; c = 3
a, b, c, *d = arr # a = 1; b = 2; c = 3; d = []
a, *b, *c = arr # SyntaxError: unexpected *
arr = [1, [2, 3, 4], 5, 6]
a, (b, *c), *d = arr # a = 1; b = 2; c = [3, 4]; d = [5, 6]
Arrays union, intersection and difference
x = [5, 5, 1, 3] y = [5, 2, 4, 3]
x|y
=> [5, 1, 3, 2, 4]
x&y
=> [5, 3]
x-y => [1]
Remove all nil elements from an array with #compact
array = [ 1, nil, 'hello', nil, '5', 33] array.compact # => [ 1, 'hello', '5', 33]
#notice that the method returns a new copy of the array with nil removed,
#without affecting the original
array = [ 1, nil, 'hello', nil, '5', 33]
#If you need the original array modified, you can either reassign it array = array.compact # => [ 1, 'hello', '5', 33]
array = [ 1, 'hello', '5', 33]
#Or you can use the much more elegant 'bang' version of the method array = [ 1, nil, 'hello', nil, '5', 33]
array.compact # => [ 1, 'hello', '5', 33]
array = [ 1, 'hello', '5', 33]
Get all combinations / permutations of an array
[1,2,3].permutation
[1,2,3].permutation.to_a
[1,2,3].permutation(2).to_a [[1,2],[1,3],[2,1],[2,3],[3,1],[3,2]] [1,2,3].permutation(4).to_a [] -> No permutations of length 4
[1,2,3].combination(1) #<Enumerator: [1,2,3]:combination [1,2,3].combination(1).to_a [[1],[2],[3]] [1,2,3].combination(3).to_a [[1,2,3]] [1,2,3].combination(4).to_a [] -> No combinations of length 4
Inject, reduce
[1,2,3].reduce(0) {|a,b| a + b} # => 6
[1,2,3].reduce {|a,b| a + b} # => 6
[1,2,3].reduce(0, :+) # => 6
[1,2,3].reduce(:+) # => 6
Filtering arrays
Select
array = [1, 2, 3, 4, 5, 6]
array.select { |number| number > 3 } # => [4, 5, 6]
Reject
array = [1, 2, 3, 4, 5, 6]
array.reject { |number| number > 3 } # => [1, 2, 3]
#map
[1, 2, 3].map { |i| i * 3 } # => [3, 6, 9]
['1', '2', '3', '4', '5'].map { |i| i.to_i } # => [1, 2, 3, 4, 5]
# call to_i method on all elements
%w(1 2 3 4 5 6 7 8 9 10).map(&:to_i) # => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# using proc (lambda) on all elements
%w(1 2 3 4 5 6 7 8 9 10).map(&->(i){ i.to_i * 2}) # => [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
Arrays and the splat (*) operator
def wrap_in_array(value) [*value]
end
wrap_in_array(1) #> [1]
wrap_in_array([1, 2, 3]) #> [1, 2, 3]
wrap_in_array(nil) #> []
Two-dimensional array
array = Array.new(3) { Array.new(4) { 0 } }
Turn multi-dimensional array into a one- dimensional (flattened) array
[1, 2, [[3, 4], [5]], 6].flatten # => [1, 2, 3, 4, 5, 6]
Get unique array elements
a = [1, 1, 2, 3, 4, 4, 5]
a.uniq
#=> [1, 2, 3, 4, 5]
Create Array of numbers
numbers = Array(1..10) # => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
numbers = (1..10).to_a # => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Create an Array of consecutive numbers or letters
(1..10).to_a #=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
a_range = 1...5
a_range.to_a #=> [1, 2, 3, 4]
Cast to Array from any object
def join_as_string(arg)
if arg.instance_of?(Array)
arg.join(',')
elsif arg.instance_of?(Range)
arg.to_a.join(',') else
arg.to_s end
end
join_as_string('something') join_as_string([2, 1, 5]) join_as_string(1) join_as_string(2..4) join_as_string([]) join_as_string(nil)
#=> "something"
#=> "2,1,5"
#=> "1"
#=> "2,3,4"
#=> ""
#=> ""
String
Difference between single-quoted and double-quoted String literals
# Single-quoted strings don't support interpolation
puts 'Now is #{Time.now}' # Now is #{Time.now}
# Double-quoted strings support interpolation
puts "Now is #{Time.now}"
# Now is 2016-07-21 12:43:04 +0200
puts 'Hello\nWorld' # Hello\nWorld
puts "Hello\nWorld" # Hello
# World
Creating a String
s1 = 'Hello'
s2 = "Hello"
%(A string) %{A string} %<A string> %|A string| %!A string!
Case manipulation
"string".upcase
"STRING".downcase "String".swapcase "string".capitalize # => "String"
String concatenation
s1 = "Hello"
s2 = " "
s3 = "World"
puts s1 + s2 + s3
# => Hello World
s = s1 + s2 + s3 puts s
# => Hello World
Positioning strings
str ="abcd"
str.ljust(4) => "abcd" str.ljust(10) => "abcd
str = "abcd"
str.rjust(4) => "abcd" str.rjust(10) => " abcd"
str = "abcd"
str.center(4) => "abcd" str.center(10) => " abcd "
Splitting a String
"alpha,beta".split(",")
# => ["alpha", "beta"]
String starts with
str = "zebras are cool"
str.start_with?("zebras") => true
str = "zebras are cool"
str.index("zebras").zero? => true
Joining Strings
["alpha", "beta"].join(",") # => "alpha,beta"
["alpha", "beta"].join # => "alphabeta"
String ends with
str = "I like pineapples" str.end_with?("pineaaples") => false
String Substitution
p "This is %s" % "foo" # => "This is foo"
p "%s %s %s" % ["foo", "bar", "baz"] # => "foo bar baz"
p "%{foo} == %{foo}" % {:foo => "foo" } # => "foo == foo"
String character replacements
"string".tr('r', 'l') # => "stling"
"string ring".sub('r', 'l') # => "stling ring"
"string ring".gsub('r','l') # => "stling ling"
Understanding the data in a string
"abc".bytes # => [97, 98, 99] "abc".encoding.name # => "UTF-8"
DateTime
DateTime from string
DateTime.parse('Jun, 8 2016')
# => #<DateTime: 2016-06-08T00:00:00+00:00 ((2457548j,0s,0n),+0s,2299161j)> DateTime.parse('201603082330')
# => #<DateTime: 2016-03-08T23:30:00+00:00 ((2457456j,84600s,0n),+0s,2299161j)> DateTime.parse('04-11-2016 03:50')
# => #<DateTime: 2016-11-04T03:50:00+00:00 ((2457697j,13800s,0n),+0s,2299161j)> DateTime.parse('04-11-2016 03:50 -0300')
# => #<DateTime: 2016-11-04T03:50:00-03:00 ((2457697j,24600s,0n),-10800s,2299161j)
New
DateTime.new(2014,10,14)
# => #<DateTime: 2014-10-14T00:00:00+00:00 ((2456945j,0s,0n),+0s,2299161j)>
DateTime.now
# => #<DateTime: 2016-08-04T00:43:58-03:00 ((2457605j,13438s,667386397n),-10800s,2299161j)>
Add/subtract days to DateTime
DateTime.new(2015,12,30,23,0) + 1
# => #<DateTime: 2015-12-31T23:00:00+00:00 ((2457388j,82800s,0n),+0s,2299161j)>
DateTime.new(2015,12,30,23,0) + 2.5
# => #<DateTime: 2016-01-02T11:00:00+00:00 ((2457390j,39600s,0n),+0s,2299161j)>
DateTime.new(2015,12,30,23,0) + Rational(1,2)
# => #<DateTime: 2015-12-31T11:00:00+00:00 ((2457388j,39600s,0n),+0s,2299161j)>
DateTime.new(2015,12,30,23,0) - 1
# => #<DateTime: 2015-12-29T23:00:00+00:00 ((2457388j,82800s,0n),+0s,2299161j)>
DateTime.new(2015,12,30,23,0) - 2.5
DateTime.new(2015,12,30,23,0) - Rational(1,2)
# => #<DateTime: 2015-12-30T11:00:00+00:00 ((2457387j,39600s,0n),+0s,2299161j)>
Time
How to use the strftime method
Time.now.strftime("%Y-%m-d %H:%M:S") #=> "2016-07-27 08:45:42"
Time.now.strftime("%F %X") #=> "2016-07-27 08:45:42"
Creating time objects
Time.new(2010, 3, 10) #10 March 2010 (Midnight)
Time.new(2015, 5, 3, 10, 14) #10:14 AM on 3 May 2015
Time.new(2050, "May", 3, 21, 8, 16, "+10:00") #09:08:16 PM on 3 May 2050
Time.now.to_i # => 1478633386
Time.at(1478633386) # => 2016-11-08 17:29:46 -0200
Numbers
Converting a String to Integer
Integer("123") Integer("0xFF") Integer("0b100") Integer("0555")
# => 123
# => 255
# => 4
# => 365
"23".to_i
"23-hello".to_i
"hello".to_i
# => 23
# => 23
# => 0
Creating an Integer
0 # creates the Fixnum 0
123 # creates the Fixnum 123
1_000 # creates the Fixnum 1000. You can use _ as separator for readability
Rounding Numbers
4.89.round 4.25.round 3.141526.round(1) 3.141526.round(2) 3.141526.round(4)
# => 5
# => 4
# => 3.1
# => 3.14
# => 3.1415
4.9999999999999.floor # => 4
4.0000000000001.ceil # => 5
Even and Odd Numbers
4.even? # => true 5.even? # => false
4.odd? # => false 5.odd? # => true
Rational Numbers
r1 = Rational(2, 3)
r2 = 2.5.to_r
r3 = r1 + r2
r3.numerator # => 19 r3.denominator # => 6 Rational(2, 4) # => (1/2)
Rational('2/3') Rational(3) Rational(3, -5) Rational(0.2) Rational('0.2') 0.2.to_r 0.2.rationalize '1/4'.to_r
# => (2/3)
# => (3/1)
# => (-3/5)
# => (3602879701896397/18014398509481984)
# => (1/5)
# => (3602879701896397/18014398509481984)
# => (1/5)
# => (1/4)
Complex Numbers
1i # => (0+1i)
1.to_c # => (1+0i)
rectangular = Complex(2, 3) # => (2+3i)
polar = Complex('1@2') # => (-0.4161468365471424+0.9092974268256817i)
Converting a number to a string
2.to_s(2)
3.to_s(2)
3.to_s(3) 10.to_s(16) # => "a"
Dividing two numbers
3 / 2 # => 1
3 / 3.0 # => 1.0
Symbols
Creating a Symbol
:a_symbol # => :a_symbol :a_symbol.class # => Symbol
Converting a String to Symbol
s.to_sym
# => :something
:"#{s}"
# => :something
Converting a Symbol to String
s = :something
s.to_s
# => "something"
Comparable
Rectangle comparable by area
class Rectangle include Comparable
def initialize(a, b) @a = a
@b = b end
def area @a * @b
end
def <=>(other)
area <=> other.area
end end
r1 = Rectangle.new(1, 1) r2 = Rectangle.new(2, 2) r3 = Rectangle.new(3, 3)
r2 >= r1 # => true r2.between? r1, r3 # => true r3.between? r1, r2 # => false
Control Flow
if, elsif, else and end
status = if age < 18 :minor
else
:adult
end
Case statement
case x when 1,2,3
puts "1, 2, or 3" when 10
puts "10" else
puts "Some other number" end
case x
when 1,2,3 then puts "1, 2, or 3" when 10 then puts "10"
else puts "Some other number"
end
Truthy and Falsy values
two values which are considered “falsy”
- nil
- false
Inline if/unless
puts "x is less than 5" if x < 5
while, until
i= 0
while i < 5
puts "Iteration ##{i}"
i +=1 end
i= 0
until i == 5
puts "Iteration ##{i}"
i +=1 end
Flip-Flop operator
(1..5).select do |e|
e if (e == 2) .. (e == 4)
end
# => [2, 3, 4]
``
### Or-Equals/Conditional assignment operator (||=)
### unless
```ruby
# Prints not inclusive
unless 'hellow'.include?('all') puts 'not inclusive'
end
throw, catch
catch(:out) do
catch(:nested) do
puts "nested" end
puts "before"
throw :out
puts "will not be executed"
end
puts "after"
# prints "nested", "before", "after"
Ternary operator
value = true
value ? "true" : "false" #=> "true"
value = false
value ? "true" : "false" #=> "false"
Loop control with break, next, and redo
actions = %w(run jump swim exit macarena) index = 0
while index < actions.length action = actions[index]
break if action == "exit"
index += 1
puts "Currently doing this action: #{action}" end
# Currently doing this action: run
# Currently doing this action: jump
# Currently doing this action: swim
actions = %w(run jump swim sleep macarena) index = 0
repeat_count = 0
while index < actions.length
action = actions[index]
puts "Currently doing this action: #{action}"
if action == "sleep" repeat_count += 1
redo if repeat_count < 3
end
index += 1 end
# Currently doing this action: run
# Currently doing this action: jump
# Currently doing this action: swim
# Currently doing this action: sleep
# Currently doing this action: sleep
# Currently doing this action: sleep
# Currently doing this action: macarena
even_value = for value in [1, 2, 3] break value if value.even?
end
puts "The first even value is: #{even_value}"
return vs. next: non-local return in a block
def foo
bar = [1, 2, 3, 4].map do |x|
return 0 if x.even?
x
end
puts 'baz'
bar
end
foo # => 0
begin, end
begin
a= 7 b= 6 a*b
end
Control flow with logic statements
File.exist?(filename) or STDERR.puts "#{filename} does not exist!"