wbzyl-datamapper-tutorial 0.0.8 → 0.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.markdown +9 -7
 - data/Rakefile +8 -8
 - data/VERSION.yml +4 -0
 - data/config.ru +0 -5
 - data/lib/config.ru +12 -0
 - data/lib/datamapper-tutorial.rb +20 -5
 - data/lib/public/doc/plain-text-files/contacts.yaml +11 -0
 - data/lib/public/doc/plain-text-files/contacts_g.rb +105 -0
 - data/lib/public/doc/plain-text-files/contacts_g_test.rb +51 -0
 - data/lib/public/doc/plain-text-files/contacts_y.rb +57 -0
 - data/lib/public/doc/plain-text-files/contacts_y_test.rb +39 -0
 - data/lib/public/doc/plain-text-files/gdbm-example.rb +22 -0
 - data/lib/public/doc/plain-text-files/gdbm_contacts/Ja/305/233_Ma/305/202gosia/extras +0 -0
 - data/lib/public/doc/plain-text-files/gdbm_contacts/Ja/305/233_Ma/305/202gosia/home +0 -0
 - data/lib/public/doc/plain-text-files/gdbm_contacts/Ja/305/233_Ma/305/202gosia/work +0 -0
 - data/lib/public/doc/plain-text-files/gdbm_contacts/Joe_Smith/extras +0 -0
 - data/lib/public/doc/plain-text-files/gdbm_contacts/Joe_Smith/home +0 -0
 - data/lib/public/doc/plain-text-files/gdbm_contacts/Joe_Smith/work +0 -0
 - data/lib/public/doc/using-plain-text-files-for-data-persistence.pdf +0 -0
 - data/lib/public/images/datamapper.png +0 -0
 - data/lib/public/images/datamapper.svg +95 -0
 - data/lib/public/stylesheets/datamapper.css +160 -0
 - data/lib/public/stylesheets/fonts/Cyklop-Italic.otf +0 -0
 - data/lib/public/stylesheets/ie.css +1 -0
 - data/lib/public/stylesheets/screen.css +48 -66
 - data/lib/public/stylesheets/uv.css +121 -0
 - data/lib/views/intro.rdiscount +10 -0
 - data/lib/views/layout.rdiscount +28 -7
 - data/lib/views/main.rdiscount +16 -6
 - data/lib/views/using-plain-text-files-for-data-persistence.rdiscount +53 -0
 - metadata +32 -12
 - data/lib/public/Onyx_Mother_O_Pearl.html +0 -122
 - data/lib/public/stylesheets/application.css +0 -113
 - data/lib/public/stylesheets/coderay.css +0 -99
 
    
        data/README.markdown
    CHANGED
    
    | 
         @@ -2,16 +2,18 @@ 
     | 
|
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            1. [pastie](http://www.dzone.com/links/datamapper_sinatra_tutorial.html),
         
     | 
| 
       4 
4 
     | 
    
         
             
               [pastie2](http://blog.zerosum.org/2008/7/2/clone-pastie-with-sinatra-datamapper-redux).
         
     | 
| 
       5 
     | 
    
         
            -
            2. [ 
     | 
| 
      
 5 
     | 
    
         
            +
            2. [apps written in sinatra, uses datamapper](http://github.com/zapnap/mogo/)
         
     | 
| 
       6 
6 
     | 
    
         
             
            3. [A simple Twitter application template, built in Ruby with 
         
     | 
| 
       7 
7 
     | 
    
         
             
               Sinatra and DataMapper](http://github.com/zapnap/retweet/)
         
     | 
| 
       8 
     | 
    
         
            -
               
         
     | 
| 
       9 
8 
     | 
    
         | 
| 
       10 
     | 
    
         
            -
            ##  
     | 
| 
      
 9 
     | 
    
         
            +
            ## Data persistence   
         
     | 
| 
       11 
10 
     | 
    
         | 
| 
       12 
     | 
    
         
            -
            1.  
     | 
| 
       13 
     | 
    
         
            -
             
     | 
| 
      
 11 
     | 
    
         
            +
            1. [using plain-text files for data persistence](/doc/using-plain-text-files-for-data-persistence.pdf)
         
     | 
| 
      
 12 
     | 
    
         
            +
            1. [ohm](http://ohm.keyvalue.org/) — Object-hash mapping library for 
         
     | 
| 
      
 13 
     | 
    
         
            +
               [Redis](http://code.google.com/p/redis/). Datamapper adapter for Redis:
         
     | 
| 
      
 14 
     | 
    
         
            +
               [DataMapper loves Redis](http://whoahbot.com/2009/05/27/redis-and-datamapper.html)
         
     | 
| 
      
 15 
     | 
    
         
            +
               \([source, example](http://github.com/whoahbot/dm-redis-adapter/)\).
         
     | 
| 
       14 
16 
     | 
    
         | 
| 
       15 
     | 
    
         
            -
             
     | 
| 
       16 
     | 
    
         
            -
                           1_000_000         : czas?
         
     | 
| 
      
 17 
     | 
    
         
            +
            ## Todo
         
     | 
| 
       17 
18 
     | 
    
         | 
| 
      
 19 
     | 
    
         
            +
            1. redis.spec for Fedora?
         
     | 
    
        data/Rakefile
    CHANGED
    
    | 
         @@ -13,13 +13,13 @@ Moje notatki do Datamappera. 
     | 
|
| 
       13 
13 
     | 
    
         
             
                EOF
         
     | 
| 
       14 
14 
     | 
    
         
             
                s.summary      = "Prosta aplikacja Sinatry."
         
     | 
| 
       15 
15 
     | 
    
         | 
| 
       16 
     | 
    
         
            -
                s.files        = %w[TODO Rakefile config.ru VERSION.yml] + FileList["lib/**/*"]
         
     | 
| 
      
 16 
     | 
    
         
            +
                s.files        = %w[LICENSE TODO Rakefile config.ru VERSION.yml] + FileList["lib/**/*"]
         
     | 
| 
       17 
17 
     | 
    
         | 
| 
       18 
18 
     | 
    
         
             
                s.add_dependency 'rack' 
         
     | 
| 
       19 
19 
     | 
    
         
             
                s.add_dependency 'sinatra'
         
     | 
| 
       20 
20 
     | 
    
         
             
                s.add_dependency 'rdiscount'
         
     | 
| 
       21 
     | 
    
         
            -
                s.add_dependency 'sinatra-rdiscount'
         
     | 
| 
       22 
     | 
    
         
            -
                s.add_dependency 'codehighlighter-middleware'
         
     | 
| 
      
 21 
     | 
    
         
            +
                s.add_dependency 'wbzyl-sinatra-rdiscount'
         
     | 
| 
      
 22 
     | 
    
         
            +
                s.add_dependency 'wbzyl-codehighlighter-middleware'
         
     | 
| 
       23 
23 
     | 
    
         
             
                s.add_dependency 'coderay'
         
     | 
| 
       24 
24 
     | 
    
         | 
| 
       25 
25 
     | 
    
         
             
                s.rubyforge_project = 'datamapper-tutorial'
         
     | 
| 
         @@ -31,8 +31,8 @@ rescue LoadError 
     | 
|
| 
       31 
31 
     | 
    
         
             
              puts "  sudo gem install technicalpickles-jeweler -s http://gems.github.com"
         
     | 
| 
       32 
32 
     | 
    
         
             
            end
         
     | 
| 
       33 
33 
     | 
    
         | 
| 
       34 
     | 
    
         
            -
            Rake::TestTask.new(:test) do |t|
         
     | 
| 
       35 
     | 
    
         
            -
              t.libs << 'lib' << 'test'
         
     | 
| 
       36 
     | 
    
         
            -
              t.pattern = 'test/**/*_test.rb'
         
     | 
| 
       37 
     | 
    
         
            -
              t.verbose = false
         
     | 
| 
       38 
     | 
    
         
            -
            end
         
     | 
| 
      
 34 
     | 
    
         
            +
            #Rake::TestTask.new(:test) do |t|
         
     | 
| 
      
 35 
     | 
    
         
            +
            #  t.libs << 'lib' << 'test'
         
     | 
| 
      
 36 
     | 
    
         
            +
            #  t.pattern = 'test/**/*_test.rb'
         
     | 
| 
      
 37 
     | 
    
         
            +
            #  t.verbose = false
         
     | 
| 
      
 38 
     | 
    
         
            +
            #end
         
     | 
    
        data/VERSION.yml
    ADDED
    
    
    
        data/config.ru
    CHANGED
    
    | 
         @@ -3,11 +3,6 @@ 
     | 
|
| 
       3 
3 
     | 
    
         
             
            $LOAD_PATH.unshift("#{File.dirname(__FILE__)}/lib")
         
     | 
| 
       4 
4 
     | 
    
         
             
            require 'config'
         
     | 
| 
       5 
5 
     | 
    
         | 
| 
       6 
     | 
    
         
            -
            #FileUtils.mkdir_p 'log' unless File.exists?('log')
         
     | 
| 
       7 
     | 
    
         
            -
            #log = File.new("log/sinatra.log", "a")
         
     | 
| 
       8 
     | 
    
         
            -
            #STDOUT.reopen(log)
         
     | 
| 
       9 
     | 
    
         
            -
            #STDERR.reopen(log)
         
     | 
| 
       10 
     | 
    
         
            -
             
     | 
| 
       11 
6 
     | 
    
         
             
            # require 'rack/cache'
         
     | 
| 
       12 
7 
     | 
    
         
             
            # use Rack::Cache
         
     | 
| 
       13 
8 
     | 
    
         
             
            run WB_DatamapperTutorial
         
     | 
    
        data/lib/config.ru
    ADDED
    
    | 
         @@ -0,0 +1,12 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'datamapper-tutorial'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            gem 'wbzyl-rack-codehighlighter'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require 'rack/codehighlighter'
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            gem 'ultraviolet'
         
     | 
| 
      
 7 
     | 
    
         
            +
            require 'uv'
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            use Rack::ShowExceptions
         
     | 
| 
      
 10 
     | 
    
         
            +
            use Rack::Lint
         
     | 
| 
      
 11 
     | 
    
         
            +
            use Rack::Codehighlighter, :ultraviolet, :element => '//pre/code', :markdown => true
         
     | 
| 
      
 12 
     | 
    
         
            +
            run WB::DatamapperTutorial.new
         
     | 
    
        data/lib/datamapper-tutorial.rb
    CHANGED
    
    | 
         @@ -2,16 +2,25 @@ 
     | 
|
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            # Zobacz przykład: http://gist.github.com/38605
         
     | 
| 
       4 
4 
     | 
    
         | 
| 
       5 
     | 
    
         
            -
            gem 'rdiscount'
         
     | 
| 
       6 
     | 
    
         
            -
            gem 'sinatra'
         
     | 
| 
       7 
     | 
    
         
            -
             
     | 
| 
      
 5 
     | 
    
         
            +
            #gem 'rdiscount'
         
     | 
| 
      
 6 
     | 
    
         
            +
            #gem 'sinatra'
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            #gem 'wbzyl-sinatra-rdiscount'
         
     | 
| 
      
 9 
     | 
    
         
            +
            #gem 'emk-sinatra-url-for'
         
     | 
| 
      
 10 
     | 
    
         
            +
            #gem 'wbzyl-sinatra-static-assets'
         
     | 
| 
       8 
11 
     | 
    
         | 
| 
       9 
12 
     | 
    
         
             
            require 'rdiscount'
         
     | 
| 
       10 
13 
     | 
    
         
             
            require 'sinatra/base'
         
     | 
| 
       11 
14 
     | 
    
         
             
            require 'sinatra/rdiscount'
         
     | 
| 
       12 
15 
     | 
    
         | 
| 
      
 16 
     | 
    
         
            +
            require 'sinatra/url_for'
         
     | 
| 
      
 17 
     | 
    
         
            +
            require 'sinatra/static_assets'
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
       13 
19 
     | 
    
         
             
            module WB
         
     | 
| 
       14 
20 
     | 
    
         
             
              class DatamapperTutorial < Sinatra::Base
         
     | 
| 
      
 21 
     | 
    
         
            +
                helpers Sinatra::UrlForHelper
         
     | 
| 
      
 22 
     | 
    
         
            +
                helpers Sinatra::StaticAssets
         
     | 
| 
      
 23 
     | 
    
         
            +
                
         
     | 
| 
       15 
24 
     | 
    
         
             
                # disable overriding public and views dirs
         
     | 
| 
       16 
25 
     | 
    
         
             
                set :app_file, __FILE__
         
     | 
| 
       17 
26 
     | 
    
         
             
                set :static, true  
         
     | 
| 
         @@ -33,7 +42,14 @@ module WB 
     | 
|
| 
       33 
42 
     | 
    
         | 
| 
       34 
43 
     | 
    
         
             
                # helper methods
         
     | 
| 
       35 
44 
     | 
    
         | 
| 
       36 
     | 
    
         
            -
                 
     | 
| 
      
 45 
     | 
    
         
            +
                def page_title
         
     | 
| 
      
 46 
     | 
    
         
            +
                  @title || ""
         
     | 
| 
      
 47 
     | 
    
         
            +
                end
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
                # def title=(name)... does not work, bug?
         
     | 
| 
      
 50 
     | 
    
         
            +
                def title(name)
         
     | 
| 
      
 51 
     | 
    
         
            +
                  @title = " | #{name}"
         
     | 
| 
      
 52 
     | 
    
         
            +
                end
         
     | 
| 
       37 
53 
     | 
    
         | 
| 
       38 
54 
     | 
    
         
             
                get '/' do
         
     | 
| 
       39 
55 
     | 
    
         
             
                  rdiscount :main
         
     | 
| 
         @@ -53,4 +69,3 @@ module WB 
     | 
|
| 
       53 
69 
     | 
    
         
             
                use Rack::Lint
         
     | 
| 
       54 
70 
     | 
    
         
             
              end
         
     | 
| 
       55 
71 
     | 
    
         
             
            end
         
     | 
| 
       56 
     | 
    
         
            -
             
     | 
| 
         @@ -0,0 +1,105 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'gdbm'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'fileutils'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            class ContactList
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
              attr_reader :contact_cache
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
              def initialize(dir)
         
     | 
| 
      
 9 
     | 
    
         
            +
                @dir = dir
         
     | 
| 
      
 10 
     | 
    
         
            +
                @contact_cache = []
         
     | 
| 
      
 11 
     | 
    
         
            +
              end
         
     | 
| 
      
 12 
     | 
    
         
            +
              
         
     | 
| 
      
 13 
     | 
    
         
            +
              def [](name)
         
     | 
| 
      
 14 
     | 
    
         
            +
                contact = @contact_cache.find {|c| c.name == name }
         
     | 
| 
      
 15 
     | 
    
         
            +
                return contact if contact
         
     | 
| 
      
 16 
     | 
    
         
            +
                contact = Contact.new(name)
         
     | 
| 
      
 17 
     | 
    
         
            +
                Dir.chdir(@dir) do
         
     | 
| 
      
 18 
     | 
    
         
            +
                  if File.directory?(contact.dirname)
         
     | 
| 
      
 19 
     | 
    
         
            +
                    populate_contact(contact)
         
     | 
| 
      
 20 
     | 
    
         
            +
                    @contact_cache << contact
         
     | 
| 
      
 21 
     | 
    
         
            +
                  else
         
     | 
| 
      
 22 
     | 
    
         
            +
                    contact = nil
         
     | 
| 
      
 23 
     | 
    
         
            +
                  end
         
     | 
| 
      
 24 
     | 
    
         
            +
                end
         
     | 
| 
      
 25 
     | 
    
         
            +
                contact
         
     | 
| 
      
 26 
     | 
    
         
            +
              end
         
     | 
| 
      
 27 
     | 
    
         
            +
              
         
     | 
| 
      
 28 
     | 
    
         
            +
              def populate_contact(contact)
         
     | 
| 
      
 29 
     | 
    
         
            +
                Dir.chdir(contact.dirname) do
         
     | 
| 
      
 30 
     | 
    
         
            +
                  contact.open
         
     | 
| 
      
 31 
     | 
    
         
            +
                end
         
     | 
| 
      
 32 
     | 
    
         
            +
              end
         
     | 
| 
      
 33 
     | 
    
         
            +
              
         
     | 
| 
      
 34 
     | 
    
         
            +
              def <<(contact)
         
     | 
| 
      
 35 
     | 
    
         
            +
                Dir.chdir(@dir) do
         
     | 
| 
      
 36 
     | 
    
         
            +
                  Dir.mkdir(contact.dirname) unless File.exists?(contact.dirname)
         
     | 
| 
      
 37 
     | 
    
         
            +
                  populate_contact(contact)
         
     | 
| 
      
 38 
     | 
    
         
            +
                end
         
     | 
| 
      
 39 
     | 
    
         
            +
                @contact_cache << contact
         
     | 
| 
      
 40 
     | 
    
         
            +
              end
         
     | 
| 
      
 41 
     | 
    
         
            +
              
         
     | 
| 
      
 42 
     | 
    
         
            +
              def delete(name)
         
     | 
| 
      
 43 
     | 
    
         
            +
                contact = self[name]
         
     | 
| 
      
 44 
     | 
    
         
            +
                return false unless contact
         
     | 
| 
      
 45 
     | 
    
         
            +
                contact.close
         
     | 
| 
      
 46 
     | 
    
         
            +
                Dir.chdir(@dir) do
         
     | 
| 
      
 47 
     | 
    
         
            +
                  FileUtils.rm_rf(contact.dirname)
         
     | 
| 
      
 48 
     | 
    
         
            +
                end
         
     | 
| 
      
 49 
     | 
    
         
            +
                contact_cache.delete_if {|c| c.name == name }
         
     | 
| 
      
 50 
     | 
    
         
            +
                true
         
     | 
| 
      
 51 
     | 
    
         
            +
              end
         
     | 
| 
      
 52 
     | 
    
         
            +
              
         
     | 
| 
      
 53 
     | 
    
         
            +
              def directory_names
         
     | 
| 
      
 54 
     | 
    
         
            +
                Dir["#{@dir}/*"]
         
     | 
| 
      
 55 
     | 
    
         
            +
              end
         
     | 
| 
      
 56 
     | 
    
         
            +
              
         
     | 
| 
      
 57 
     | 
    
         
            +
              def size
         
     | 
| 
      
 58 
     | 
    
         
            +
                directory_names.size
         
     | 
| 
      
 59 
     | 
    
         
            +
              end
         
     | 
| 
      
 60 
     | 
    
         
            +
              
         
     | 
| 
      
 61 
     | 
    
         
            +
              def empty?
         
     | 
| 
      
 62 
     | 
    
         
            +
                directory_names.empty?
         
     | 
| 
      
 63 
     | 
    
         
            +
              end
         
     | 
| 
      
 64 
     | 
    
         
            +
              
         
     | 
| 
      
 65 
     | 
    
         
            +
            end
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
            class Contact
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
              COMPONENTS = ["home", "extras", "work"]
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
              attr_accessor :name, *COMPONENTS
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
              attr_reader :dirname
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
              def initialize(name)
         
     | 
| 
      
 77 
     | 
    
         
            +
                @name = name
         
     | 
| 
      
 78 
     | 
    
         
            +
                @dirname = @name.gsub(" ", "_")
         
     | 
| 
      
 79 
     | 
    
         
            +
              end
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
              def components
         
     | 
| 
      
 82 
     | 
    
         
            +
                COMPONENTS.map {|comp_name| self.send(comp_name) }
         
     | 
| 
      
 83 
     | 
    
         
            +
              end
         
     | 
| 
      
 84 
     | 
    
         
            +
              
         
     | 
| 
      
 85 
     | 
    
         
            +
              def open
         
     | 
| 
      
 86 
     | 
    
         
            +
                COMPONENTS.each do |component|
         
     | 
| 
      
 87 
     | 
    
         
            +
                  self.send(component + "=", GDBM.new(component))
         
     | 
| 
      
 88 
     | 
    
         
            +
                end
         
     | 
| 
      
 89 
     | 
    
         
            +
              end
         
     | 
| 
      
 90 
     | 
    
         
            +
              
         
     | 
| 
      
 91 
     | 
    
         
            +
              def close
         
     | 
| 
      
 92 
     | 
    
         
            +
                components.each do |component|
         
     | 
| 
      
 93 
     | 
    
         
            +
                  component.close unless component.closed?
         
     | 
| 
      
 94 
     | 
    
         
            +
                end
         
     | 
| 
      
 95 
     | 
    
         
            +
              end
         
     | 
| 
      
 96 
     | 
    
         
            +
             
     | 
| 
      
 97 
     | 
    
         
            +
              def email
         
     | 
| 
      
 98 
     | 
    
         
            +
                extras["email"]
         
     | 
| 
      
 99 
     | 
    
         
            +
              end
         
     | 
| 
      
 100 
     | 
    
         
            +
              
         
     | 
| 
      
 101 
     | 
    
         
            +
              def email=(e)
         
     | 
| 
      
 102 
     | 
    
         
            +
                extras["email"] = e
         
     | 
| 
      
 103 
     | 
    
         
            +
              end
         
     | 
| 
      
 104 
     | 
    
         
            +
             
         
     | 
| 
      
 105 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,51 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'test/unit'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'contacts_g'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            Dir.mkdir("gdbm_contacts") unless File.exist?("gdbm_contacts")
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            class GDBMTest < Test::Unit::TestCase
         
     | 
| 
      
 7 
     | 
    
         
            +
              
         
     | 
| 
      
 8 
     | 
    
         
            +
              def setup
         
     | 
| 
      
 9 
     | 
    
         
            +
                @list = ContactList.new("gdbm_contacts")
         
     | 
| 
      
 10 
     | 
    
         
            +
                @contact = Contact.new("Joe Smith")
         
     | 
| 
      
 11 
     | 
    
         
            +
                
         
     | 
| 
      
 12 
     | 
    
         
            +
                @list << @contact
         
     | 
| 
      
 13 
     | 
    
         
            +
                
         
     | 
| 
      
 14 
     | 
    
         
            +
                @contact.home["street1"] = "123 Main Street"
         
     | 
| 
      
 15 
     | 
    
         
            +
                @contact.home["city"] = "Somewhere"
         
     | 
| 
      
 16 
     | 
    
         
            +
                @contact.work["phone"] = "(000) 123-4567"
         
     | 
| 
      
 17 
     | 
    
         
            +
                @contact.extras["instrument"] = "Cello"
         
     | 
| 
      
 18 
     | 
    
         
            +
                @contact.email = "joe@somewhere.abc"
         
     | 
| 
      
 19 
     | 
    
         
            +
              end
         
     | 
| 
      
 20 
     | 
    
         
            +
              
         
     | 
| 
      
 21 
     | 
    
         
            +
              def teardown
         
     | 
| 
      
 22 
     | 
    
         
            +
                @list.delete("Joe Smith") if @list["Joe Smith"]
         
     | 
| 
      
 23 
     | 
    
         
            +
              end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
              def test_retrieving_a_contact_from_list
         
     | 
| 
      
 26 
     | 
    
         
            +
                contact = @list["Joe Smith"]
         
     | 
| 
      
 27 
     | 
    
         
            +
                assert_equal("Joe Smith", contact.name)
         
     | 
| 
      
 28 
     | 
    
         
            +
              end
         
     | 
| 
      
 29 
     | 
    
         
            +
              
         
     | 
| 
      
 30 
     | 
    
         
            +
              def test_delete_a_contact_from_list
         
     | 
| 
      
 31 
     | 
    
         
            +
                assert(!@list.empty?)
         
     | 
| 
      
 32 
     | 
    
         
            +
                @list.delete("Joe Smith")
         
     | 
| 
      
 33 
     | 
    
         
            +
                assert(@list.empty?)
         
     | 
| 
      
 34 
     | 
    
         
            +
                assert(@list.contact_cache.empty?)
         
     | 
| 
      
 35 
     | 
    
         
            +
              end
         
     | 
| 
      
 36 
     | 
    
         
            +
              
         
     | 
| 
      
 37 
     | 
    
         
            +
              def test_home
         
     | 
| 
      
 38 
     | 
    
         
            +
                contact = @list["Joe Smith"]
         
     | 
| 
      
 39 
     | 
    
         
            +
                assert_equal("123 Main Street", contact.home["street1"])
         
     | 
| 
      
 40 
     | 
    
         
            +
              end
         
     | 
| 
      
 41 
     | 
    
         
            +
              
         
     | 
| 
      
 42 
     | 
    
         
            +
              def test_email
         
     | 
| 
      
 43 
     | 
    
         
            +
                contact = @list["Joe Smith"]
         
     | 
| 
      
 44 
     | 
    
         
            +
                assert_equal("joe@somewhere.abc", contact.email)
         
     | 
| 
      
 45 
     | 
    
         
            +
              end
         
     | 
| 
      
 46 
     | 
    
         
            +
              
         
     | 
| 
      
 47 
     | 
    
         
            +
              def test_non_existent_contact_is_nil
         
     | 
| 
      
 48 
     | 
    
         
            +
                assert_equal(nil, @list["Some Person"])
         
     | 
| 
      
 49 
     | 
    
         
            +
              end
         
     | 
| 
      
 50 
     | 
    
         
            +
              
         
     | 
| 
      
 51 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,57 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require "yaml"
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            class ContactList
         
     | 
| 
      
 4 
     | 
    
         
            +
             attr_accessor :contacts          
         
     | 
| 
      
 5 
     | 
    
         
            +
                                              
         
     | 
| 
      
 6 
     | 
    
         
            +
             def initialize(file)
         
     | 
| 
      
 7 
     | 
    
         
            +
               @file = file
         
     | 
| 
      
 8 
     | 
    
         
            +
               @contacts = []
         
     | 
| 
      
 9 
     | 
    
         
            +
             end                      
         
     | 
| 
      
 10 
     | 
    
         
            +
                                      
         
     | 
| 
      
 11 
     | 
    
         
            +
             def <<(contact)
         
     | 
| 
      
 12 
     | 
    
         
            +
               @contacts << contact
         
     | 
| 
      
 13 
     | 
    
         
            +
             end                      
         
     | 
| 
      
 14 
     | 
    
         
            +
                                      
         
     | 
| 
      
 15 
     | 
    
         
            +
             def delete(name)
         
     | 
| 
      
 16 
     | 
    
         
            +
               @contacts.delete_if {|c| c.name == name }
         
     | 
| 
      
 17 
     | 
    
         
            +
             end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
         
     | 
| 
      
 19 
     | 
    
         
            +
             def empty?
         
     | 
| 
      
 20 
     | 
    
         
            +
               @contacts.empty?
         
     | 
| 
      
 21 
     | 
    
         
            +
             end
         
     | 
| 
      
 22 
     | 
    
         
            +
             
         
     | 
| 
      
 23 
     | 
    
         
            +
             def size
         
     | 
| 
      
 24 
     | 
    
         
            +
               @contacts.size
         
     | 
| 
      
 25 
     | 
    
         
            +
             end
         
     | 
| 
      
 26 
     | 
    
         
            +
             
         
     | 
| 
      
 27 
     | 
    
         
            +
             def [](name)
         
     | 
| 
      
 28 
     | 
    
         
            +
               @contacts.find {|c| c.name == name }
         
     | 
| 
      
 29 
     | 
    
         
            +
             end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
         
     | 
| 
      
 31 
     | 
    
         
            +
             def save
         
     | 
| 
      
 32 
     | 
    
         
            +
               File.open(@file, "w") do |fh|
         
     | 
| 
      
 33 
     | 
    
         
            +
                 fh.puts(@contacts.to_yaml)
         
     | 
| 
      
 34 
     | 
    
         
            +
               end
         
     | 
| 
      
 35 
     | 
    
         
            +
             end
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
             def self.load(file)
         
     | 
| 
      
 38 
     | 
    
         
            +
               list = new(file)
         
     | 
| 
      
 39 
     | 
    
         
            +
               list.contacts = YAML.load(File.read(file))
         
     | 
| 
      
 40 
     | 
    
         
            +
               list
         
     | 
| 
      
 41 
     | 
    
         
            +
             end
         
     | 
| 
      
 42 
     | 
    
         
            +
             
         
     | 
| 
      
 43 
     | 
    
         
            +
            end
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
            class Contact
         
     | 
| 
      
 47 
     | 
    
         
            +
              attr_reader :name, :email, :home, :work, :extras
         
     | 
| 
      
 48 
     | 
    
         
            +
              attr_writer :name, :email
         
     | 
| 
      
 49 
     | 
    
         
            +
              
         
     | 
| 
      
 50 
     | 
    
         
            +
              def initialize(name)
         
     | 
| 
      
 51 
     | 
    
         
            +
                @name = name
         
     | 
| 
      
 52 
     | 
    
         
            +
                @home = {}
         
     | 
| 
      
 53 
     | 
    
         
            +
                @work = {}
         
     | 
| 
      
 54 
     | 
    
         
            +
                @extras = {}
         
     | 
| 
      
 55 
     | 
    
         
            +
              end
         
     | 
| 
      
 56 
     | 
    
         
            +
              
         
     | 
| 
      
 57 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,39 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require "test/unit"
         
     | 
| 
      
 2 
     | 
    
         
            +
            require "contacts_y"
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            class TestContacts < Test::Unit::TestCase
         
     | 
| 
      
 5 
     | 
    
         
            +
              
         
     | 
| 
      
 6 
     | 
    
         
            +
              def setup
         
     | 
| 
      
 7 
     | 
    
         
            +
                @filename = "contacts.yaml"
         
     | 
| 
      
 8 
     | 
    
         
            +
                @list = ContactList.new(@filename)
         
     | 
| 
      
 9 
     | 
    
         
            +
                @contact = Contact.new("Joe Smith")
         
     | 
| 
      
 10 
     | 
    
         
            +
                
         
     | 
| 
      
 11 
     | 
    
         
            +
                @contact.email = "joe@somewhere.abc"
         
     | 
| 
      
 12 
     | 
    
         
            +
                @contact.home[:street1] = "123 Main Street"
         
     | 
| 
      
 13 
     | 
    
         
            +
                @contact.home[:city] = "Somewhere"
         
     | 
| 
      
 14 
     | 
    
         
            +
                @contact.work[:phone] = "(000) 123-4567"
         
     | 
| 
      
 15 
     | 
    
         
            +
                @contact.extras[:instrument] = "Cello"
         
     | 
| 
      
 16 
     | 
    
         
            +
                
         
     | 
| 
      
 17 
     | 
    
         
            +
                @list << @contact
         
     | 
| 
      
 18 
     | 
    
         
            +
              end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
              def test_retrieve_contact_from_list
         
     | 
| 
      
 21 
     | 
    
         
            +
                contact = @list["Joe Smith"]
         
     | 
| 
      
 22 
     | 
    
         
            +
                assert_equal("Joe Smith", contact.name)
         
     | 
| 
      
 23 
     | 
    
         
            +
              end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
              def test_delete_contact_from_list
         
     | 
| 
      
 26 
     | 
    
         
            +
                assert(!@list.empty?)
         
     | 
| 
      
 27 
     | 
    
         
            +
                @list.delete(@contact.name)
         
     | 
| 
      
 28 
     | 
    
         
            +
                assert(@list.empty?)
         
     | 
| 
      
 29 
     | 
    
         
            +
              end
         
     | 
| 
      
 30 
     | 
    
         
            +
              
         
     | 
| 
      
 31 
     | 
    
         
            +
              def test_save_and_load_list
         
     | 
| 
      
 32 
     | 
    
         
            +
                @list.save
         
     | 
| 
      
 33 
     | 
    
         
            +
                relist = ContactList.load(@filename)
         
     | 
| 
      
 34 
     | 
    
         
            +
                assert_equal(1, relist.size)
         
     | 
| 
      
 35 
     | 
    
         
            +
                contact = relist["Joe Smith"]
         
     | 
| 
      
 36 
     | 
    
         
            +
                assert_equal("Joe Smith", contact.name)
         
     | 
| 
      
 37 
     | 
    
         
            +
              end
         
     | 
| 
      
 38 
     | 
    
         
            +
              
         
     | 
| 
      
 39 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,22 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'gdbm'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            movies = GDBM.new("movies.db")
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            movies.update(
         
     | 
| 
      
 6 
     | 
    
         
            +
                          { "Vertigo" => "Alfred Hitchcock",
         
     | 
| 
      
 7 
     | 
    
         
            +
                            "In a Lonely Place" => "Nicholas Ray",
         
     | 
| 
      
 8 
     | 
    
         
            +
                            "Johnny Guitar" => "Nicholas Ray",
         
     | 
| 
      
 9 
     | 
    
         
            +
                            "Touch of Evil" => "Orson Welles",
         
     | 
| 
      
 10 
     | 
    
         
            +
                            "Psycho" => "Alfred Hitchcock",
         
     | 
| 
      
 11 
     | 
    
         
            +
                          })
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            movies.close
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            __END__
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
            # irb session
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
            require "gdbm"
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
            movies = GDBM.new("movies.db")
         
     | 
| 
      
 22 
     | 
    
         
            +
            movies.values.uniq
         
     | 
| 
         Binary file 
     | 
| 
         Binary file 
     | 
| 
         Binary file 
     | 
| 
         Binary file 
     | 
| 
         Binary file 
     |