Ruby overview

 




  1. System Ruby (apt-get, brew)
  2. RVM (Ruby Version Manager)


Installation

RVM

http://rvm.io/


  • Install
  • $ rvm list known
  • $ rvm install 
  • $ rvm use --default ruby-1.9.3
  • $ rvm use jruby
  • .rvmrc file

IRB (Interactive Ruby)





$ irb

Everything is an Object

No Primitives

> 'c'.upcase

'C'

> "cat".reverse

"tac"

> 12.even?

true

> x.nil?

true


Scripting language

#!/usr/bin/ruby
def foo
  bar
end

def bar
  ...
end

foo 

Dynamically typed language


  • No type declarations / Duck typing
  • Message passing

"If it looks like a duck and quacks like a duck, it's a duck"

Dynamic typing - Example


parser = CsvParser.new(file)
parser.parse

parser = XlsParser.new(file)
parser.parse
    

Strings vs Symbols

> ["north", "south", "east", "west"]
> [:north, :south, :east, :west]

> {"a" => 1, "b" => 2}
> {a: 1, b: 2}

> "foo".object_id
> :foo.object_id

Conditionals


if c1
...
elsif c2
...
else
...
end 

unless c
...
end

while c
...
end

until c
...
end

Statement modifiers

send_email if subscribed?

show_popup unless subscribed?

wait while queue.empty?

process until queue.empty?

Array

> []

> a = [1, 2, 3]

> a = [:foo, 5, "bar"]

> a << 42


> b = [5, 10, 15]

> b.each {|element| puts element}


> c = ['foo', 'bar', 'baz']

> c.map {|s| s.upcase} 


Hash

> h = {"x" => 1, "y" => 2, "z" => 3}

> h = {x: 1, y: 2, z: 3}

> h.keys

> h.values

> h[:x]

> h[:a] = 0


> h.each {|k,v| puts "#{k} = #{v}"}


Printing

> print

> p (short for print)

> puts

> pp (short for pretty print)

Class and Object

class Book
  def initialize(isbn, title, author)
    @isbn = isbn
    @title = title
    @author = author
  end

  def author
    @author
  end

  def author=(name)
    @author = name
  end
end

catch22 = Book.newcatch22.author = "Joseph"catch22.author

Class and Object


class Book
  attr_reader :isbn
  attr_writer :title
  attr_accessor :author

  def self.search(params)
    ...
  end

  def contents
  end
end

Open classes


class String
  def palindrome?
    self == reverse
  end
end

> "stats".palindrome?

> 10.times do ... end

> 7.days.ago

> 5.days.from_now

Inheritance

class Animal
  def make_sound
    ...
  end
end

class Cat < Animal
  def make_sound
    meow
  end
end

class Dog < Animal
  def make_sound
    bark
  end
end

Modules/Mixins


module Printable
  def print
  end

  def self.remove_non_printable_chars(str)
  end
end

class Document
  include Printable
end

class Book
  include Printable
end

include / extend / included hook

module Printable
  def self.included(klass)
    klass.extend(ClassMethods)
  end

  def print ... end

  module ClassMethods
    def print_with(options={})
    end
  end
end

class Document
  include Printable
  print_with header: "---", footer: "---"
end

Functional programming - each


> [5,10,15,20,25].each do |num|
    puts num * 10
  end

> [5,10,15,20,25].each {|num| puts num * 10}

> # for loop is syntactic sugar for each
  for num in nums
    puts num * 10
  end

collect / map


> [5,10,15,20,25].collect do |num|
     num / 5
  end
  [1,2,3,4,5]
    
> [5,10,15,20,25].map {|num| num / 5}
  [1,2,3,4,5]
    
> [1,4,9,16,25].map(&:sqrt) # convert method to block
  [1,2,3,4,5]
    

select / reject


> [5,10,15,20,25].select {|num| num.even? }
  [10, 20]
    
> [5,10,15,20,25].reject {|num| num.odd? }
  [10, 20]
    

inject / reduce


> (1..100).inject(0) {|sum, num| sum + num}
5050

> (1..100).inject(&:+)
5050

> (1..5).reduce(:*)
120    

each_with_index / each_with_object


> [5,10,15].each_with_index do |num, index|
    puts "#{index} = #{num}"
  end

> ["foo", "bar", "baz"].each_with_object({}) do |s, scores|
    scores[s] = s.score
  end
  {"foo" => 5, "bar" => 12, "baz" => 13}
    

blocks


class Bookstore
  def change_prices(&block)
    books.each do |book|
      book.price = yield(book.price)
    end
  end
end

book_store.change_prices do |price|
  price * 1.10
end

book_store.change_prices do |price|
  price * 0.5
end

yield - before/after/around

Writer writer = null;
try {
    writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("foo.txt"), "utf-8"));
    writer.write("foo");
} catch (IOException ex) {
  // report
} finally {
   try {writer.close();} catch (Exception ex) {}
}
vs
File.open("foo.txt", 'w') {|f| f.write "foo"}

block, lambdas, proc


# blocks are passes as last arg to a function

> matrix.apply {|num| num * 2}

# lambdas can be stored in vars and passed around as values

> square = lambda {|num| num * num}
> matrix.apply(square)

# procs are similar to lambdas except for return

> cube = Proc.new {|num| num * num * num}
> matrix.apply(cube)

dynamic methods


Book.find_by_author_and_publisher("Joseph", "Penguin")
Book.find_by_title_and_publisher("Catch22", "Penguin")

Metaprogramming - define_method


class CreditCard
  attr_reader :number, :name, :cvv

  [:number, :name, :cvv].each do |attr|
    define_method "encrypted_#{attr}" do
      #...
    end
  end
end

> card.encrypted_cvv
> card.encrypted_name
    

Metaprogramming - send


class CreditCard
  def to_json(keys=[:number, :name, :address])
    keys.each_with_object({}) do |key, hash|
      hash[key] = send("encrypted_#{key}")
    end
  end
end

Metaprogramming - method_missing


class Book < ActiveRecord::Base
end

class ActiveRecord::Base
  def method_missing(method_name, *args, &block)
    if method_name.to_s =~ /^find_by_(.+)$/
      query($1.split("_and_"), *args, &block)
    else
      super
    end
  end
end

Book.find_by_title_and_publisher("Catch22", "Penguin")
    

DSLs


class Vehicle
  state_machine :state, :initial => :parked do

    event :park do
      transition :first_gear => :parked
    end

    event :ignite do
      transition :parked => :first_gear
    end

    event :shift_up do
      transition :first_gear => :second_gear, :second_gear => :third_gear
    end
  end
end


> car.ignite
> car.shift_up        
    

Gems - Libraries

$ gem install rails

$ gem search -ar rails

$ gem list rails


http://rubygems.org

https://www.ruby-toolbox.com




Bundler - dependency management

Gemfile

Gemfile.lock


$ bundle install

$ bundle update

$ bundle gem


http://bundler.io

Other topics

  1. Strings
  2. Regexes
  3. Testing/Debugging
  4. Exception handling
  5. eval, instance_eval, class_eval

References

deck

By sathish316

deck

  • 247