Ruby datatypes

From wikinotes

Type Checks

123.instance_of?(Integer)  # instance of exact class

123.is_a?(Integer)         # instance of class/subclass
123.kind_of?(Integer)      # instance of class/subclass

Implied Types

"A,b,C"     # string
["a", "b"]  # list
true        # boolean
nil         # null

Percent Strings

There are two variations of each of these commands.

  • lower-case letter indicates it should not support string-interpolation
  • upper-case letter indicates it should support string-interpolation
%r() # regex
%x() # shell command
%q() # string
%s() # symbol

%w() # array of strings
%i() # array of symbols

Text

Strings

name = 'Darth Vader'      # raw string
name = "Obi-Wan Kenobi"   # string (supports \n, #{variable} formatting)

description = "a very very"\
              "very very"\
              "very long string"

name.split(' ')
name.downcase
name.upcase
"F".ord                  # ascii-code for 'F'
?F                       # ascii-code for 'F'

msg <<~ HEREDOC
  abc
  def
  hij
HEREDOC

puts "Assigned Mentor: #{name}"  # string interpolation (uses variables from current scope)

Symbols

Variables beginning with a colon (ex: :variable) are symbols.
Symbols are immutable, named singleton strings. All symbols sharing a name refer to the same object.
The scope of a symbol is global - it is shared by the entire ruby program's execution (threads, modules, classes, etc)

Essentially, think of them as more memory efficient strings, for commonly reused string values.


See https://ruby-doc.org/core-2.1.2/Symbol.html
See Also http://www.troubleshooters.com/codecorn/ruby/symbols.htm

:my_symbol            # a symbol literal
:"my_symbol"          # a symbol literal

class A
  attr_reader :cat
end

:cat == A.new.cat
:cat == :cat

Numbers

1_000.00 == 1000.00  # underscores ignored in numbers

Collections

Arrays

NOTE:

Arrays in ruby are actually linked lists

list = ["a","b","c"]

list << "d"              # appends "d" to array
list.push("d")           # appends "d" to array
list.insert(0, "z")      # prepends "z" to array

['a', 'b'].concat ['c']  # extend array
#> ['a', 'b', 'c']

[].empty?                # array has no items?

[['a', 'b'], ['b', 'c']].flatten  # flatten array, stripping duplicates
#> ['a', 'b', 'c']

list = %w{ aa bb cc }    # array of words (no quotes)

list[0] = "a"
list.length                # number of items in list
list.first                 # print the first item in list
list.last                  # print the alst  item in list
list.include? 3            # check if list contains the number 3
list.grep /item-match/     # find all objects within array matching a grep-match
list.select { |x| x > 5 }  # find all objects where expression returns true
list.find                  # find first object where expression returns true

list.each { |list| puts "This item is #{list}" }   # single-line iteration over list

list.each do |list|                                # multi-line iteration over list
  puts "This item is #{list}"
  puts "multiple lines"
end

Hashes (Dictionaries)

myhash = {"a": "b"}    # {:a=>"b"}   SYMBOL as key
myhash = {"a" => "b"}  # {"a"=>"b"}  object as key

myhash.delete("a")      # pop value
myhash.slice("a", "b")  # return new hash with only these vals
myhash.transform_keys(&:to_sym)  # convert all keys to symbols
myhash.symbolize_keys            # (rails only) convert all keys to symbols

movies = {}
movies['good'] = ["mary poppins","star wars"]
movies['bad']  = ["citizen kane"]

movies.fetch('good').           #> ['mary poppins', 'star_wars']
movies.fetch('any', 'default'). #> 'default'
movies.fetch('any') do |key|.   # 'key' will be 'any' if it does not exist, or the value of movies[:any] if it does
  foo[key] = blah
end

# nesting hashes
movies['good'] = {"fantasy" => ["mary poppins","labyrinth"], 
                  "space" => ["star wars","cowboy bebop"]}

movies.update({a: 1})
movies.merge!({a: 1})

movies.keys    # print all keys of hash 'movies'
movies.values  # print all values of hash 'movies'

movies.keys.each do |key|
  puts key, my_dictionary[ key ]

Sets

Compound Types

Struct

Structs are immutable compound types.

Regular Usage

Person = Struct.new(:name, :age)
person = Person.new("alex", 31)
# => #<struct name="alex", age=31>

person.name
# => "alex"

Keyword Arguments

Person = Struct.new(:name, :age, keyword_init: true)
person = Person.new(name: "alex", age: 31)
# => #<struct name="alex", age=31>

Adding Methods

Person = Struct.new(:name, :age) do
  def matches(name:, age:)
    send(:name) == name \
      && send(:age) == age
  end
end

OpenStruct

Similar to a hash, but you access items as attributes.
Unlike a hash, keys are not normally added after the OpenStruct is created.

OpenStruct.new(a: 1, b: 2)