31 May 2011

ruby 101

by mo


Referenced from Programming Ruby 1.9 The Pragmatic Programmers’ Guide

installing ruby

  $ sudo apt-get update
  $ sudo apt-get install curl
  $ bash < <( curl -s https://rvm.beginrescueend.com/install/rvm )

Add to .bashrc

source $HOME/.rvm/scripts/rvm

then.

  $ rvm notes # follow instructions to install missing libs
  $ sudo apt-get install build-essential bison openssl libreadline5 libreadline-dev curl git-core zliblg zliblg-dev libssl-dev vim libsqlite3-0 libsqlite3-dev sqlite3 libreadline-dev libxml2-dev git-core subversion autoconf
  $ rvm install 1.9.2
  $ rvm use 1.9.2
  $ ruby -v

documentation

  $ ri GC
  $ ri GC::enable
  $ ri assoc

ruby is object-oriented

arrays and hashes

arrays and hashes are indexed collections. both store collections of objects, accessible using a key.

e.g array literal

  a = [ 1, 'cat', 3.14 ] # array with three elements
  puts "the first element is #{a[0]}"

ruby has a shortcut for creating arrays of strings

  a = [ 'ant', 'bee', 'cat', 'dog', 'elk' ]
  a[0] # => "ant"
  a = %w[ ant bee cat dog elk ]
  a[0] # => "ant"

hashes are similar to arrays. you must supply two objects for every entry, one for the key, the other for the value.

  dead_rappers = {
    'tupac'   => '1996'
    'biggie'   => '1997'
    'big l'   => '1999'
    'eazy e'   => '1995'
    'odb'   => '2004'
  }

  p dead_rappers['tupac']   # => '1996'
  p dead_rappers['biggie']  # => '1997'
  p dead_rappers['big pun']  # => nil

a hash by default returns nil when indexed by a key it doesn’t contain. to change the default value you can specify it when creating a new hash.

  histogram = Hash.new(0) # the default value 0
  histogram['ruby'] # => 0
  histogram['ruby'] = histogram['ruby'] + 1
  histogram['ruby'] # => 1

symbols

are simple constant names that you don’t have to predeclare and that are guaranteed to be unique. a symbol literal starts with a colon and is normally followed by some kind of name:

  walk(:north)
  walk(:east)

there’s no need to assign some kind of value to a symbol - 💎 takes care of that for you. ruby also guarantees that no matter where it appears in your program, a particular symbol will have the same value.

e.g

  def walk(direction)
    if direction == :north
      # ...
    end
  end

symbols are frequently used as keys in hashes.

like this

  dead_rappers = {
    :tupac    => '1996'
    :biggie   => '1997'
    :bigl     => '1999'
    :eazye    => '1995'
    :odb      => '2004'
  }

  dead_rappers[:odb] # => '2004'

in ruby 1.9 you can use name: value pairs to create a hash if the keys are symbols.

  dead_rappers = {
    tupac:    '1996'
    biggie:   '1997'
    bigl:     '1999'
    eazye:    '1995'
    odb:      '2004'
  }
  puts "big l died in #{dead_rappers[:bigl]}"

control structures

the if/elseif/else structure

  today = Time.now

  if today.saturday?
    puts "do chores around the house"
  elsif today.sunday?
    puts "chill out"
  else
    puts "go to work"
  end

the while loop

  i = 0
  while i < 100
    i+=1
  end

ruby treats nil as a false, so you can write this.

  while line = gets
    puts line.downcase
  end

statement modifiers are a cool shortcut if the body of an if or while statement is just a single express.

  if radiation > 3000
    puts "danger, will robinson"
  end

  puts "danger, will robinson" if radiation > 3000

  square = 4
  while square < 1000
    square = square * square
  end

  square = square*square while square < 1000

blocks

this is a code block:

  { puts "hello" }

so is this:

  do 
    club.enroll(person)
    person.socialize
  end

the only thing you can do with a block is associate it with a call to a method. you can do this by putting the start of the block at the end of the source line containing the method call.

  greet { puts "hi" }

the method greet is given a block. if the method has parameters, then they appear before the block:

  verbose_greet("mo", "a geek") { puts "hi" }

a method can invoke the block by calling yield.

  def call_block
    puts "start of method"
    yield
    yield
    puts "end of method"
  end

  call_block { puts "in the block" }
  output:
  start of method
  in the block
  in the block
  end of method

you can also pass arguments to the block. within the block you need to list the names of the parameters to receive these arguments between vertical bars.

  def who_says_what
    yield("mo", "hello")
    yield("morilla", "yo")
  end

  who_says_what {|person, phrase| puts "#{person} says #{phrase}"

code blocks are used throughout the ruby library to implement iterators, which are methods that return successive elements from some kind of collection, such as an array:

  animals = %w( ant bee cat dog elk )
  animals.each {|animal| puts animal }
  [ 'cat', 'dog', 'horse' ].each {|name| print name, " "}
  5.times { print "*" }
  3.upto(6) {|i| print i }
  ('a'..'e').each {|char| print char}
💎 oop books