Programming in Ruby
by Dave Thomas and Andy Hunt 


Example 1: 

class Song
  def initialize(title)
    @title = title
  end
  def to s
    @title
  end
end
aSong = Song.new("My Way")


Example 2: 

class KaraokeSong < Song
  def initialize(title, lyric)
    super(title)
    @lyric = lyric
  end
  def to s
    super + " [#@lyric]"
  end
end

Example 3: 

class Song
  # ...
  def title         # attribute reader
    @title          # returns instance variable
  end
  def title=(title) # attribute setter
    @title = title 
  end
end


Example 4: 

class Song
  # ...
  attr accessor :title
end

Example 5: 

def fibUpTo(max)
  n1, n2 = 1, 1
  while n1 <= max
    yield n1             # invoke block value
    n1, n2 = n2, n1+n2   # and calculate next
  end
end


Example 6: 

fibUpTo(1000) {|term| print term, " "} 
   produces:
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987


Example 7: 

class LinkedList
  # ...
  def each
    node = head
    while node
      yield node
      node = node.next
    end
  end
end


Example 8: 

module Enumerable
  def find
    each {|val| return val if yield(val)} end
  end
class Array
  include Enumerable
end


Listing One
require "socket"
class WebSession
  def initialize(connection)
    @connection = connection
  end
  def write(string)
    @connection.write string
  end
  def standardPage(title)
    write "HTTP/1.1 200 OK\r\n"
    write "Content-Type: text/html\r\n\r\n"
    write "<html><head> <title># {title} </title> </head>\n"
    write yield if block given?
    write "</body></html>"
  end
end
class WebServer
  def initialize(port)
    @listen = TCPServer.new('localhost', port || 8080);
  end
  def run
    loop do
      Thread.start(@listen.accept) do |aConnection|
        begin
          session = WebSession.new(aConnection)
          request = []
          loop do
            line = aConnection.gets.chomp("\r\n")
            break if line.length == 0
            request << line
        end
        session.standardPage("Your Request") { 
          "<h1>Your request was:</h1>\n" +
          request.join('<br>') +
          "<p>Thank you for testing our system."
        } 
       ensure
        aConnection.close
       end   # begin
     end     # Thread
   end       # loop
 end
end
WebServer.new(ARGV[0]).run


Listing Two
require 'delegate'
require 'find'
class Song
  attr reader :title, :album, :artist
  def initialize(filename)
    @artist, @album, @title = filename.split("/")[-3..-1]
    @title.chomp!(".mp3")
  end
  def <=>(anOther)
    title <=> anOther.title
  end
  def to s
    "'#{@title}' #{@artist} --'#{@album}'\n"
  end
end
class MP3List < SimpleDelegator
  def initialize(base)
    songlist = Array.new
    Find.find(base) do |entry|
      if entry =~ /\.mp3$/
        if !block given? or yield entry
          songlist << Song.new(entry)
        end
      end
    end
    super(songlist)
  end
  def shuffle!
    newlist = Array.new
    length.times do
      newlist << delete at(rand(length))
    end
    _setobj_(newlist)
    self
  end
end
base = ARGV[0] || "/mp3"
list = MP3List.new(base + "/Hatfield And The North")
puts "Original: ", list.sort
puts "Shuffled: ", list.shuffle!
puts "5 entries: ", list[0..4]
puts "Filtered: "
list = MP3List.new(base) {|x| x =~ /Woke Up This Morning/} puts list

Listing Three
class MP3List < Array
  def initialize(base)
    super()
    Find.find(base) do |entry|
      if entry =~ /\.mp3$/
        if !block given? or yield entry
           self << Song.new(entry)
        end
      end
    end
  end
  def shuffle!
    newlist = Array.new
    length.times do
      newlist << delete at(rand(length))
    end
    replace(newlist)
  end
end






4

