Andrew Chen

Andrew Chen

SDE @ StripeMS CS '19 @ UW-MadisonEnthusiastic about creating tools to make life better.

Ruby

Back

Convention

  • snake case for variable
  • Most of time when a method end with !, it means the Object which calls the method will be changed

    h1.merge(h2) -> Create new object in the heap
    h1.merge!(h2) -> Update h1

  • module represents the file-hierarchy ContactInfo::Email, can find email.rb in contact_info directory

String

str = '123456'
str.count

# Returns a new String with the given record separator removed from the end of str (if present).
# If $/ has not been changed from the default Ruby record separator, then chomp also removes carriage return characters (that is it will remove n, r, and rn).

"hello".chomp                #=> "hello"
"hello\n".chomp              #=> "hello"
"hello\r\n".chomp            #=> "hello"
"hello\r".chomp              #=> "hello"
"hello \n there".chomp       #=> "hello \n there"
"hello".chomp("llo")         #=> "he"
"hello\r\n\r\n".chomp('')    #=> "hello"

Array

# init 3 * 4 with default value 0
arr = Array.new(3) { Array.new(4) {0} }

# slicing
nums = [1,2,3,4,5,6]

nums[0..2] # [1,2,3]
nums[0...2] # [1,2]
nums[-2..-1] # [5,6]
nums[-2...-1] # [5]

# find occurance of elements
nums.count(1) # 1
# find max among array
nums.max # 6

Hash

# equalivent to python defaultdict
dic = Hash.new { |h, k| h[k] = 0 }

Proc

Block

  # multi-line block
  [1,2,3].map do |num|
    puts num
  end

  # one-line block
  [1,2,3].map { |num| puts number }

yield

def map(array)
  temp_array = []

  for item in array # step 1: item(1)

    # step 2: yield send item(1) to block as number && step 4: get number*2(1*2 = 2), assign to element
    element = yield(item)
    temp_array.push element
  end

  temp_array # [2]
end

map([1, 2, 3]) do |number|
  number * 2 #step 3: execute and return the last line
end

# output
2
4
6

yield returns the last evaluated expression.
In order to use value returned, need to assign it to varable, such as value = yield(...)

Methods

map

[1,2,3].map { |num| num.to_s }

[1,2,3].map(&:to_s)

tap

How tap is implemented

class Object
  def tap
    yield self
    self
  end
end

Yield self to the block. The primary purpose of this method is to “tap into” a method chain. (Act as a temporary pipe)

(1..10).tap {|x| puts "original: #{x}" }
  .to_a.tap { |x| puts "array:#{x}" }
  .select {|x| x.even? }.tap {|x| puts "evens: #{x}" }
  .map {|x| x*x }.tap {|x| puts "squares: #{x}" }

# output
original: 1..10
array:[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
evens: [2, 4, 6, 8, 10]
squares: [4, 16, 36, 64, 100]

It can also be used for creation

user = User.new.tap do |u|
  u.firstname = "andrew"
  u.firstname = "chen"
  u.save!
end

Reference: Ruby: Tap that method, API Doc

File

# read file line by lin
file = File.open(filename)
file.readlines.map(&:chomp).each do |line|
  # do something with line
end
file.close

# write something to the file
file = File.open(filename, 'w')
file.write('TEST')
file.close

File.open(filename, 'w') { |f| f.write "Test\n" }

Class

method

  • instance_method == instance method in Java
    Object needs to be created to call the method
    @instance_variable is used by instance_method
    Use @ sign for instance variable
  • class_method == static method in Java
    Use self for class method
    @class_variable is used by class_method
class Person
  def instance_var
    @instance_var = "instance variable"
  end

  def self.class_var
    @@class_var = "class varialbe"
  end

  def say_hi
    "Hi I am #{@instance_var}"
  end

  def self.say_hi
    "Hi I am #{@class_var}"
  end
end

bob = Person.new
bob.say_hi # => Hi I am instance variable
Person.say_hi # => Hi I am class variable

3 ways to create class method Reference

# Way 1
class Foo
  def self.bar
    puts 'class method'
  end
end

# Way 2
class Foo
  class << self
    def bar
      puts 'class method'
    end
  end
end

# Way 3
class Foo; end
def Foo.bar
  puts 'class method'
end

Example:

module ActiveRecord
  class Base
    def self.validates_presence_of(...)
      # make sure present
    end
  end
end

class Foo < ActiveRecord::Base
  validates_presence_of :bar
end

instacne_eval vs class_eval vs module_eval Reference

# class_eval
MyClass.class_eval do
  def num
    @num
  end
end

# is the same as

class MyClass
  def num
    @num
  end
end

Code outside of a method: Reference