Personal Notes on Learning Rails 2

each, map and times

>> (1..5).each{|i| puts i**2}
1
4
9
16
25
=> 1..5

>> (1..5).map{|i| i**2}
=> [1, 4, 9, 16, 25]

>> 3.times { puts "Betelgeuse!" }   # 3.times takes a block with no variables.
"Betelgeuse!"
"Betelgeuse!"
"Betelgeuse!"
=> 3

>> %w[a b c]                 # Recall that %w makes string arrays.
=> ["a", "b", "c"]
>> %w[a b c].map { |char| char.upcase }
=> ["A", "B", "C"]
>> %w[A B C].map { |char| char.downcase }
=> ["a", "b", "c"]

map method returns the result of applying the given block to each element in the array or range.

%w and -1

>> a = %w[foo bar baz quux]    # Use %w to make a string array.

>> a = %w[0 1 2 3 4 5 6 7 8 9]
>> a[2..-1]                    # Use the index -1 trick.
=> ["2", "3", "4", "5", "6", "7", "8", "9"]

bang!, push, <<

>> a
=> [42, 8, 17]
>> a.sort!
=> [8, 17, 42]
>> a
=> [8, 17, 42]

>> a.push(6)                  # Pushing 6 onto an array
=> [42, 8, 17, 6]
>> a << 7                     # Pushing 7 onto an array
=> [42, 8, 17, 6, 7]
>> a << "foo" << "bar"        # Chaining array pushes
=> [42, 8, 17, 6, 7, "foo", "bar"]

join and split

split convert a string to an array. join method from an array to a string.

>> a
=> [42, 8, 17, 7, "foo", "bar"]
>> a.join                       # Join on nothing.
=> "428177foobar"
>> a.join(', ')                 # Join on comma-space.
=> "42, 8, 17, 7, foo, bar"

to_a and range

# converting a range to arrays using the to_a method
>> (0..9).to_a            # Use parentheses to call to_a on the range.
=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

>> a = %w[foo bar baz quux]         # Use %w to make a string array.
=> ["foo", "bar", "baz", "quux"]
>> a[0..2]
=> ["foo", "bar", "baz"]

# Using rang on array
>> a[2..-1]                         # Use the index -1 trick.
=> [2, 3, 4, 5, 6, 7, 8, 9]

Curly braces and do..end

Using curly braces only for short one-line blocks and the do..end syntax for longer one-liners and for multi-line blocks:

shuffle

>> ('a'..'z').to_a.shuffle[0..7].join
=> "bjglxomw"
>> ('a'..'z').to_a.shuffle[0..7]
=> ["y", "h", "l", "v", "i", "d", "p", "f"]

Hashes and symbols

>> user = {}                          # {} is an empty hash.
=> {}
>> user["first_name"] = "Michael"     # Key "first_name", value "Michael"
=> "Michael"
>> user["last_name"] = "Hartl"        # Key "last_name", value "Hartl"
=> "Hartl"
>> user["first_name"]                 # Element access is like arrays.
=> "Michael"
>> user                               # A literal representation of the hash
=> {"last_name"=>"Hartl", "first_name"=>"Michael"}

Hashes don’t generally guarantee keeping their elements in a particular order. If order matters, use an array.

# hashrocket => 
>> user = { "first_name" => "Michael", "last_name" => "Hartl" }
=> {"last_name"=>"Hartl", "first_name"=>"Michael"}

Symbols

Symbols are a special Ruby data type

>> user = { :name => "Michael Hartl", :email => "michael@example.com" }
=> {:name=>"Michael Hartl", :email=>"michael@example.com"}
>> user[:name]
=> "Michael Hartl"

# New notation with :
>> h1 = { :name => "Michael Hartl", :email => "michael@example.com" }
=> {:name=>"Michael Hartl", :email=>"michael@example.com"}
>> h2 = { name: "Michael Hartl", email: "michael@example.com" }
=> {:name=>"Michael Hartl", :email=>"michael@example.com"} 
>> h1 == h2
=> true

The each method for arrays takes a block with only one variable, each for hashes takes two, a key and a value.

>> flash = { success: "It worked!", error: "It failed." }
=> {:success=>"It worked!", :error=>"It failed."}
>> flash.each do |key, value|
?>   puts "Key #{key.inspect} has value #{value.inspect}"
>> end
Key :success has value "It worked!"
Key :error has value "It failed."

inspect

inspect returns a string with a literal representation of the object it’s called on.

>> puts (1..5).to_a            # Put an array as a string.
1
2
3
4
5
>> puts (1..5).to_a.inspect    # Put a literal array.
[1, 2, 3, 4, 5]
>> p :name             # Same as 'puts :name.inspect'
:name

notes

Parenthesese and curly braces on the final hash are optional.

# Parentheses on function calls are optional.
stylesheet_link_tag("application", :media => "all")
stylesheet_link_tag "application", :media => "all"

# Curly braces on final hash arguments are optional.
stylesheet_link_tag "application", { :media => "all" }
stylesheet_link_tag "application", :media => "all"
# outputs
<link href="/assets/application.css" media="all" rel="stylesheet"
type="text/css" />

Classes

contructor

>> s = "foobar" 

>> s = String.new("foobar") 

>> a = Array.new([1, 3, 2])

# Hash is different
>> h = Hash.new
=> {}
>> h[:foo]            # Try to access the value for the nonexistent key :foo.
=> nil
>> h = Hash.new(0)    # Arrange for nonexistent keys to return 0 instead of nil.
=> {}
>> h[:foo]
=> 0

Array constructor Array.new takes an initial value for the array, Hash.new takes a default value for the hash, which is the value of the hash for a nonexistent key.

superclass

>> s = String.new("foobar")
=> "foobar"
>> s.class                        # Find the class of s.
=> String
>> s.class.superclass             # Find the superclass of String.
=> Object
>> s.class.superclass.superclass  # Ruby 1.9 uses a new BasicObject base class
=> BasicObject 
>> s.class.superclass.superclass.superclass
=> nil

Class inheritance

>> class Word
>>   def palindrome?(string)
>>     string == string.reverse
>>   end
>> end
=> nil
>> w = Word.new              # Make a new Word object.
=> #<Word:0x22d0b20>
>> w.palindrome?("foobar")
=> false
>> w.palindrome?("level")
=> true


# Better solution
>> class Word < String             # Word inherits from String.
>>   # Returns true if the string is its own reverse.
>>   def palindrome?
>>     self == self.reverse        # self is the string itself.
>>   end
>> end
=> nil
>> s = Word.new("level")    # Make a new Word, initialized with "level".
=> "level"                  
>> s.palindrome?            # Words have the palindrome? method.
=> true                     
>> s.length                 # Words also inherit all the normal string methods.
=> 5

Modifing built-in classes (temporarily)

# This doesn't work
>> "level".palindrome?

# so modify String class
>> class String
>>   # Returns true if the string is its own reverse.
>>   def palindrome?
>>     self == self.reverse
>>   end
>> end
=> nil
>> "deified".palindrome?
=> true

# find it out in methods
>> "test".methods.sort

Once you get out of irb, then it is not available any more. It’s considered bad form to add methods to built-in classes without having a really good reason.

rails' blank

Rails adds a blank? method to Ruby.

Written on July 8, 2013