├── 10
├── Rakefile
├── compressor1.rb
├── compressor1_spec.rb
├── compressor2.rb
├── compressor2_spec.rb
├── compressor3.rb
├── compressor4_spec.rb
├── compressor_examples.rb
├── ex_compressor3_spec.rb
├── ex_compressor4.rb
├── ex_prose_rating1_spec.rb
├── ex_prose_rating2_spec.rb
├── ex_prose_rating3_spec.rb
├── pretentious_examples.rb
└── simple_memo.rb
├── 11
├── Rakefile
├── doc_plus.rb
├── ex_1_adddoc_spec.rb
├── ex_1_operators_are_methods_spec.rb
├── ex_2_array_shift_spec.rb
├── ex_3_doc_ops_spec.rb
├── ex_4_mix_opts_spec.rb
├── ex_5_real_world_spec.rb
└── known_words.txt
├── 12
├── Rakefile
├── document_identifier.rb
├── ex_10_good_key_spec.rb
├── ex_11_disarray_spec.rb
├── ex_12_real_world.rb
├── ex_1_equal_spec.rb
├── ex_2_impl_double_equals_spec.rb
├── ex_3_fast_double_equals_spec.rb
├── ex_4_responds_to_spec.rb
├── ex_5_kind_of_spec.rb
├── ex_6_responds_to_spec.rb
├── ex_7_trans_spec.rb
├── ex_8_regexp_spec.rb
├── ex_9_bad_key_spec.rb
└── known_words.txt
├── 13
├── Rakefile
├── ex_3_uri_spec.rb
├── ex_4_date_spec.rb
├── ex_examples1_spec.rb
├── ex_examples2_spec.rb
├── ex_examples3_spec.rb
├── ex_examples4_spec.rb
├── ex_examples5_spec.rb
├── mocha_demo.rb
├── t1.rb
└── telling.txt
├── 14
├── Rakefile
├── document_with_accessor_iv.rb
├── document_with_cv.rb
├── document_with_default_font.rb
├── document_with_iv.rb
├── document_with_iv_examples.rb
├── document_with_silly_instance_variable_spec.rb
├── ex_1_document_with_cv_spec.rb
├── ex_2_resume_presentation_spec.rb
├── ex_3_doc_disaster_spec.rb
├── ex_4_more_doc_disaster_spec.rb
├── ex_5_document_with_iv_spec.rb
├── ex_6_document_with_accessor_spec.rb
├── ex_7_resume_presentation_with_iv_spec.rb
├── ex_8_wild.rb
├── presentation.rb
├── resume.rb
└── resume_presentation_with_iv.rb
├── 15
├── Rakefile
├── demo_bit_at_a_time.rb
├── ex_print_papersize_demo.rb
├── ex_rendering.rb
├── ex_rendering_spec.rb
├── ex_wp_points_spec.rb
├── known_words.txt
├── mod_printer_classes.rb
├── mod_printer_classes_spec.rb
├── printer_classes.rb
├── trouble_mod_bad.rb
├── trouble_mod_bad_spec.rb
├── trouble_mod_good.rb
├── trouble_mod_good_spec.rb
├── word_processor.rb
├── word_processor_spec.rb
└── wp_points.rb
├── 16
├── Rakefile
├── electronic_text.rb
├── ex_1_doc_with_method_spec.rb
├── ex_2_ns_module_spec.rb
├── ex_3_prose_quality_mixin_spec.rb
├── ex_4_multiple_modules_spec.rb
├── ex_5_class_mixin_spec.rb
├── ex_6_class_extend_spec.rb
├── ex_7_override_with_local_method_spec.rb
├── ex_8_override_with_another_module_spec.rb
├── ex_9_include_constants_spec.rb
├── prose_quality_examples.rb
└── writing_quality_mixin.rb
├── 17
├── Rakefile
├── doc_each_word.rb
├── doc_with_each_char.rb
├── ex_1_basic_examples_spec.rb
├── ex_2_basic_doc_iterator_spec.rb
├── ex_3_easy_doc_iterator_spec.rb
├── ex_4_each_char_spec.rb
├── ex_5_each_word_pair_spec.rb
├── ex_6_doc_with_enum_spec.rb
├── ex_7_enumerator_spec.rb
├── ex_8_trouble.rb
├── ex_8a_except_spec.rb
├── ex_8b_each_name_ensure_spec.rb
├── ex_8c_break_spec.rb
└── ex_9_real_world_spec.rb
├── 18
├── Rakefile
├── doc_with_load_save.rb
├── ex_10_names_spec.rb
├── ex_1_simple_load_save_spec.rb
├── ex_2_simple_with_logging_spec.rb
├── ex_3_load_save_with_logging_spec.rb
├── ex_4_special_logging_methods_spec.rb
├── ex_5_swith_logging_spec.rb
├── ex_6_degenerative_xaround_spec.rb
├── ex_7_init_block_spec.rb
├── ex_8_bogus_object_spec.rb
├── ex_8a_with_database_spec.rb
├── ex_9_return_value_spec.rb
└── some_application_examples.rb
├── 19
├── Rakefile
├── doc_block_listeners.rb
├── ex_1_explicit_blocks_spec.rb
├── ex_2_doc_with_on_save_spec.rb
├── ex_3_listener_classes_spec.rb
├── ex_4_block_load_save_spec.rb
├── ex_5_archival_doc_spec.rb
├── ex_6_block_based_lazy_doc_spec.rb
├── ex_7_lambda_spec.rb
├── ex_7a_proc.rb
├── ex_8_big_array_spec.rb
├── ex_8a_array_no_block_spec.rb
├── ex_8b_big_array_fixed_spec.rb
├── ex_9_spec.rb
├── example.txt
└── saveload.txt
├── 20
├── Rakefile
├── at_exit_demo.rb
├── autoloader.rb
├── autoloader_spec.rb
├── bye.txt
├── document_reader.rb
├── ex_1_inherit_spec.rb
├── ex_1_reader_spec.rb
├── ex_2_included_spec.rb
├── ex_3_extend_include_spec.rb
├── ex_4_include_with_auto_extend_spec.rb
├── ex_4a_exit_spec.rb
├── ex_5_trace_spec.rb
├── ex_6_when_spec.rb
├── ex_7_unexpected_inherit_spec.rb
├── inherit.txt
├── inherited_demo.rb
├── plain.txt
├── plaintext_reader.rb
├── readers.rb
├── trace.txt
├── trace_func_demo.rb
├── xml_reader.rb
└── yaml_reader.rb
├── 21
├── Rakefile
├── ex_1_spec.rb
├── ex_2_repeat_spec.rb
├── ex_3_doc_missing_spec.rb
├── ex_4_doc_to_file_spec.rb
├── ex_5_soundex_spec.rb
├── ex_6_autoload_const_spec.rb
├── ex_6_const_missing_spec.rb
├── ex_7_autoload_const_spec.rb
└── example.rb
├── 22
├── Rakefile
├── ex_delegate_spec.rb
├── ex_ssdoc1_spec.rb
├── ex_ssdoc2_spec.rb
├── ex_ssdoc3_spec.rb
├── ex_ssdoc4_spec.rb
├── ex_ssdoc5_spec.rb
└── ssdoc_mm.rb
├── 23
├── Rakefile
├── ex_formletter1_spec.rb
├── ex_formletter2_spec.rb
├── ex_formletter3_spec.rb
├── ex_formletter4_spec.rb
├── ex_taskargs_spec.rb
└── ostruct_spec.rb
├── 24
├── Rakefile
├── document.rb
├── ex_1_spec.rb
├── ex_alias_method_spec.rb
├── ex_alias_patch_spec.rb
├── ex_fix_bug_spec.rb
├── ex_no_wordcount_spec.rb
├── ex_private_wordcount_spec.rb
├── ex_public_wordcount_spec.rb
└── ex_string_patch_spec.rb
├── 25
├── Rakefile
├── broken_encrypting_document.rb
├── encrypting_document.rb
├── ex_1_mostly_spec.rb
├── ex_2_one_step_spec.rb
├── ex_3_sep_classes_spec.rb
├── ex_3_twice_spec.rb
├── ex_4_encrypt_spec.rb
├── ex_5_toggle_encryption_spec.rb
├── ex_6_char_at_spec.rb
├── ex_7_char_at_switch_spec.rb
├── ex_8_reload_spec.rb
├── ex_9_better_reloadable_spec.rb
├── reloadable_document.rb
├── reloadable_document2.rb
└── trouble_document.rb
├── 26
├── Rakefile
├── disclaimer.txt
├── ex_1_struc_doc_spec.rb
├── ex_2_resume_spec.rb
├── ex_3_ins_spec.rb
├── ex_4_meta_ins_spec.rb
├── ex_4_question_spec.rb
├── ex_5_def_method_spec.rb
├── ex_6_private_doc_spec.rb
├── ex_7_private_with_class_meth_spec.rb
├── ex_8_attrs_spec.rb
├── ex_8_dumb_attrs_spec.rb
├── ex_8_simple_attr_spec.rb
├── ex_9_forwardable.rb
├── forw.rb
├── my_attr.rb
├── structured_doc_def_method.rb
├── structured_doc_eval.rb
└── structured_document.rb
├── 27
├── Rakefile
├── Rakefile.example
├── broken.ripper
├── ex_1_author.rb
├── ex_1_fix.rb
├── ex_1_simple_spec.rb
├── ex_1_title.rb
├── fellowship.xml
├── fix_author.ripper
├── fix_author_comments.ripper
├── migration_example.rb
├── on_doc_author.ripper
├── ripper1.rb
├── ripper1_fix_author.rb
├── ripper1_spec.rb
├── ripper1_title_author.rb
├── ripper2.rb
├── ripper2_demo.rb
├── ripper2_spec.rb
├── ripper3.rb
├── ripper3_demo.rb
├── ripper3_spec.rb
├── ripper4.rb
├── ripper4_main.rb
├── ripper4_spec.rb
├── ripper5.rb
└── ripper5_main.rb
├── 28
├── Rakefile
├── bad_delete.ezr
├── bad_examples.rb
├── bad_print.ezr
├── bad_print_document.ezr
├── bad_replace.ezr
├── bad_statement.ezr
├── bad_upcase.ezr
├── comments.ezr
├── common.rb
├── edit.ezr
├── ex_1_spec.rb
├── ex_2_spec.rb
├── ex_3_spec.rb
├── ex_4_spec.rb
├── ex_6_spec.rb
├── ex_erb_spec.rb
├── ex_haml_spec.rb
├── example.erb
├── example.haml
├── execute.ezr
├── ez_ripper1.rb
├── ez_ripper1_demo.rb
├── ez_ripper2.rb
├── ez_ripper2_demo.rb
├── ez_ripper3.rb
├── ez_ripper3_demo.rb
├── ez_ripper4.rb
├── ez_ripper4_demo.rb
├── ez_ripper5.rb
├── ez_ripper5_demo.rb
├── ez_ripper6.rb
├── ez_ripper_statement.rb
├── ez_ripper_statement.tt
├── ez_ripper_statement_spec.rb
├── ezr.rb
├── good_examples.rb
├── print_author.ezr
├── replace_delete.ezr
├── temp.ezr
└── upcase.ezr
├── 29
├── BachGavotteShort.mp3
├── README.md
├── Rakefile
├── document_simple
│ ├── README
│ ├── Rakefile
│ ├── document.gemspec
│ ├── foo.rb
│ ├── hoe.rb
│ ├── lib
│ │ └── document.rb
│ ├── load_twice.rb
│ ├── pkg
│ │ └── document-1.0.1.gem
│ └── spec
│ │ └── document_spec.rb
├── ex_1_mp3info_spec.rb
├── ex_2_gem_cmds_spec.rb
├── ex_2_specific_version_spec.rb
├── file_test.rb
├── gem.install.04.cmd
├── gem.install.cmd
├── gem.install.many.cmd
├── gem.list.cmd
└── versions.txt
├── .gitignore
├── 01
├── Rakefile
├── case_spec.rb
├── com_with_example.rb
├── commented_doc.rb
├── count_words_in.rb
├── ex_1_fold_spec.rb
├── ex_case.rb
├── ex_comments_spec.rb
├── ex_constants_spec.rb
├── ex_semi_spec.rb
├── ex_trouble_spec.rb
├── less_simple_doc.rb
├── md
└── parens_demo.rb
├── 02
├── Rakefile
├── ex_bits_spec.rb
├── ex_case_spec.rb
├── ex_real_world_spec.rb
├── ex_trouble_spec.rb
├── known_words.txt
├── readonly_doc.rb
├── readonly_doc_with_unless.rb
├── until.rb
├── while_not.rb
└── writable_doc.rb
├── 03
├── 2001.txt
├── Rakefile
├── add_authors_spec.rb
├── add_authors_splat_spec.rb
├── bang.txt
├── bang_spec.rb
├── dc.xml
├── delete.txt
├── ex_each_index_word_len.rb
├── ex_each_word_len.rb
├── ex_for_word_len.rb
├── ex_inject_word_len.rb
├── ex_map_inject_word_len.rb
├── ex_trouble_bits_spec.rb
├── ex_word_freq_doc.rb
├── index_for_each_index_spec.rb
├── index_for_each_with_index_spec.rb
├── instant_spec.rb
├── known_words.txt
├── literal_spec.rb
├── load_font_spec.rb
├── map_inject_spec.rb
├── new_find_spec.rb
├── new_index_spec.rb
├── order.txt
├── order_spec.rb
├── reverse.txt
├── running_spec.rb
├── sizes.txt
├── superhero.txt
├── twinkle.txt
├── word_freq_doc_spec.rb
├── word_length_doc_spec.rb
└── xmlsimple_spec.rb
├── 04
├── Rakefile
├── bytes.txt
├── clarke.txt
├── examples_spec.rb
├── mars.txt
└── sub.txt
├── 05
├── Rakefile
├── ex_1_spec.rb
├── ex_2_spec.rb
├── examples_spec.rb
├── first_date.txt
├── mars.txt
└── scanning.txt
├── 06
├── Rakefile
├── add.rb
├── ex_demo.rb
├── ex_demo_ex1.rb
├── ex_demo_ex2.rb
├── examples_spec.rb
└── known_words.txt
├── 07
├── Rakefile
├── custom_to_s.txt
├── ex_10_spec.rb
├── ex_11_spec.rb
├── ex_12_spec.rb
├── ex_13_spec.rb
├── ex_1_spec.rb
├── ex_2_spec.rb
├── ex_3_spec.rb
├── ex_4_spec.rb
├── ex_5_spec.rb
├── ex_6_spec.rb
├── ex_7_spec.rb
├── ex_8_spec.rb
├── ex_9_spec.rb
├── ex_trouble_spec.rb
├── fake_irb.rb
├── print_word_count.txt
└── variables.txt
├── 08
├── Rakefile
├── cryptic_spec.rb
├── desc_doc.rb
├── desc_doc_spec.rb
├── ex_lazy_document.rb
├── ex_title_author_spec.rb
├── example.txt
├── gutted_doc.rb
├── gutted_doc_spec.rb
├── lazy_document_spec.rb
├── longer2_spec.rb
├── longer3_spec.rb
├── longer_spec.rb
├── title_author.rb
├── type_check_spec.rb
└── wild_spec.rb
├── 09
├── Rakefile
├── array_spec.rb
├── doc_spec.cmd
├── document.rb
├── document2_spec.rb
├── document_spec.rb
├── ex_assertion_test.rb
├── ex_bad_test_spec.rb
├── ex_clone_spec.rb
├── ex_document_test.rb
├── ex_longstring_spec.rb
├── ex_mock_spec.rb
├── ex_printable_document.rb
├── ex_printable_document_spec.rb
├── ex_run_document_spec.rb
├── ex_run_tests_spec.rb
├── ex_shoulda_test.rb
├── ex_simple_spec.rb
├── ex_starter_test.rb
├── if_spec.rb
├── known_words.txt
├── readable_document_spec.rb
└── tidy_document_test.rb
├── Gemfile
├── Gemfile.lock
├── README
├── Rakefile
├── code
├── Rakefile
├── doc1.rb
├── doc2.rb
├── doc3.rb
├── doc4.rb
├── doc_access.rb
├── doc_avg_word_len.rb
├── doc_init.rb
├── doc_word_count.rb
├── doc_words.rb
├── document.rb
└── simple_doc.rb
├── rvmrc.example
└── utils
├── rspec_utils.rb
└── tasks.rb
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | *.gem
3 | *.rbc
4 | .bundle
5 | .config
6 | 20/trace.txt
7 | 07/about_me.txt
8 | 07/def_to_s.txt
9 | 09/run_spec.txt
10 | 28/example.erb.out
11 | 28/example.html
12 |
--------------------------------------------------------------------------------
/01/Rakefile:
--------------------------------------------------------------------------------
1 |
2 | Targets = %w{ messy_doc.rb spec out.odt}
3 |
4 | require '../utils/tasks.rb'
5 |
6 | CLEAN.include('messy_doc.rb')
7 |
8 |
9 | file 'messy_doc.rb' do |f|
10 | code = File.read( '../code/doc3.rb' )
11 | code = code.gsub( / /, "\t" )
12 | new_code = ''
13 | count = 1
14 | code.each_char do |ch|
15 | unless ch == "\t"
16 | new_code << ch
17 | else
18 | if (count % 2) == 0
19 | new_code << ' '
20 | else
21 | new_code << ' '
22 | end
23 | end
24 | count += 1
25 | end
26 | File.open( 'messy_doc.rb', 'w') {|f| f.print(new_code)}
27 | end
28 |
--------------------------------------------------------------------------------
/01/case_spec.rb:
--------------------------------------------------------------------------------
1 | require '../utils/rspec_utils'
2 | require 'ex_case'
3 |
4 | describe "The example case statements" do
5 | it "should produce the right output with semicolons" do
6 | (output_of { case_semi( 'War And Peace' ) }).should == "Tolstoy\n"
7 | (output_of { case_semi( 'Romeo And Juliet' ) }).should == "Shakespeare\n"
8 | (output_of { case_semi( 'Whatever' ) }).should == "Don't know\n"
9 | end
10 |
11 | it "should produce the right output with semicolons" do
12 | (output_of { case_no_semi( 'War And Peace' ) }).should == "Tolstoy\n"
13 | (output_of { case_no_semi( 'Romeo And Juliet' ) }).should == "Shakespeare\n"
14 | (output_of { case_no_semi( 'Whatever' ) }).should == "Don't know\n"
15 | end
16 |
17 | end
18 |
--------------------------------------------------------------------------------
/01/com_with_example.rb:
--------------------------------------------------------------------------------
1 | # Class that models a plain text document, complete with title
2 | # and author:
3 | #
4 | # doc = Document.new( 'Hamlet', 'Shakespeare', 'To be or...' )
5 | # puts doc.title
6 | # puts doc.author
7 | # puts doc.content
8 | #
9 | # Document instances know how to parse their content into words:
10 | #
11 | # puts doc.words
12 | # puts doc.word_count
13 | #
14 | class Document
15 | # class omitted...
16 | end
17 |
--------------------------------------------------------------------------------
/01/commented_doc.rb:
--------------------------------------------------------------------------------
1 | # Class which represents a document
2 | class Document
3 |
4 | attr_accessor :title, :author, :content
5 |
6 | # Initialize the document, passing in the document tile,
7 | # the document author, and the text of the document
8 | def initialize(title, author, content)
9 | @title = title
10 | @author = author
11 | @content = content
12 | end
13 |
14 | # Return the words in the document
15 |
16 | def words
17 | @content.split
18 | end
19 |
20 | # Return the number of words in the document
21 |
22 | def word_count
23 | words.size
24 | end
25 | end
26 |
--------------------------------------------------------------------------------
/01/count_words_in.rb:
--------------------------------------------------------------------------------
1 | case Document
2 | def count_words_in( the_string ) ##(main
3 | the_words = the_string.split
4 | the_words.size
5 | end ##main)
6 | end
7 |
--------------------------------------------------------------------------------
/01/ex_1_fold_spec.rb:
--------------------------------------------------------------------------------
1 | require '../utils/rspec_utils'
2 |
3 | describe 'folding lines' do
4 |
5 | it 'should demo a one liner with braces' do
6 | out = output_of {
7 | 10.times { |n| puts "The number is #{n}" } ##+brace
8 | }
9 | out.should match( /The number.*0.*1.*2.*9$/m )
10 | end
11 |
12 | it 'should demo the do end version' do
13 | out = output_of {
14 | 10.times do |n| ##(do
15 | puts "The number is #{n}"
16 | puts "Twice the number is #{n*2}"
17 | end ##do)
18 | }
19 | out.should match( /The number.*0.*1.*2.*9$/m )
20 | end
21 | end
22 |
23 |
24 |
--------------------------------------------------------------------------------
/01/ex_case.rb:
--------------------------------------------------------------------------------
1 | ##
2 |
3 | def case_no_semi(title)
4 | ##start no_semi
5 | case title
6 | when 'War And Peace'
7 | puts 'Tolstoy'
8 | when 'Romeo And Juliet'
9 | puts 'Shakespeare'
10 | else
11 | puts "Don't know"
12 | end
13 | ##end no_semi
14 | end
15 |
16 | def case_semi(title)
17 | ##start semi
18 | case title;
19 | when 'War And Peace'; puts 'Tolstoy'
20 | when 'Romeo And Juliet'; puts 'Shakespeare'
21 | else; puts "Don't know"
22 | end
23 | ##end semi
24 | end
25 |
--------------------------------------------------------------------------------
/01/ex_constants_spec.rb:
--------------------------------------------------------------------------------
1 |
2 | describe 'constant examples' do
3 | it 'should work' do
4 | FurlongsPerFortnight = 0.0001663 ##+camel
5 | ANTLERS_PER_MALE_MOOSE = 2 ##+worm
6 |
7 | defined?(FurlongsPerFortnight).should == 'constant'
8 | defined?(ANTLERS_PER_MALE_MOOSE).should == 'constant'
9 | end
10 | end
11 |
--------------------------------------------------------------------------------
/01/ex_semi_spec.rb:
--------------------------------------------------------------------------------
1 | require '../utils/rspec_utils'
2 | require '../code/doc3'
3 |
4 |
5 | describe 'using semicolons' do
6 |
7 | it 'should let you stack statements' do
8 | doc = Document.new( 'title', 'russ', '')
9 |
10 | out = output_of {
11 | puts doc.title; puts doc.author ##+two_puts
12 | }
13 | out.should match( /title.*russ/m )
14 | end
15 |
16 | it 'should let you define a one line class' do
17 | class DocumentException < Exception; end ##+doc_exception
18 | DocumentException.instance_of?(Class).should == true
19 | end
20 |
21 | it 'should let you define a method in one line' do
22 | def method_to_be_overriden; end ##+one_line_method
23 | method_to_be_overriden
24 | end
25 |
26 | end
27 |
--------------------------------------------------------------------------------
/01/less_simple_doc.rb:
--------------------------------------------------------------------------------
1 | class Document
2 | attr_accessor :title, :author, :content
3 |
4 | def initialize(title, author, content)
5 | @title = title
6 | @author = author
7 | @content = content
8 | end
9 |
10 | def words
11 | @content.split
12 | end
13 |
14 | def word_count
15 | words.size
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/01/md:
--------------------------------------------------------------------------------
1 | class Document
2 | attr_accessor :title, :author, :content
3 |
4 | def initialize(title, author, content)
5 | @title = title
6 | @author = author
7 | @content = content
8 | end
9 |
10 | def words
11 | @content.split
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/01/parens_demo.rb:
--------------------------------------------------------------------------------
1 | # Some supporting stuff
2 |
3 | @content = 'It was a dark and stormy night'
4 |
5 |
6 | def find_document( title, author ) ##(find_parens
7 | # Body omitted...
8 | end
9 |
10 | # ...
11 |
12 | find_document( 'Frankenstein', 'Shelley' ) ##find_parens)
13 |
14 |
15 |
16 | def find_document title, author ##(find_no_parens
17 | # Body omitted...
18 | end
19 |
20 | # ...
21 |
22 | find_document 'Frankenstein', 'Shelley' ##find_no_parens)
23 |
24 |
25 | puts 'Look Ma, no parentheses!' ##+puts_no_parens
26 |
27 | def words ##(words_no_parens
28 | @content.split
29 | end ##words_no_parens)
30 |
31 | def words() ##(words_parens
32 | @content.split()
33 | end ##words_parens)
34 |
35 |
36 | if ( words.size < 100 ) ##(if_parens
37 | puts 'The document is not very long.'
38 | end ##if_parens)
39 |
40 | if words.size < 100 ##(if_no_parens
41 | puts 'The document is not very long.'
42 | end ##if_no_parens)
43 |
--------------------------------------------------------------------------------
/02/Rakefile:
--------------------------------------------------------------------------------
1 | require '../utils/tasks.rb'
2 |
--------------------------------------------------------------------------------
/02/known_words.txt:
--------------------------------------------------------------------------------
1 | NilClass
2 |
--------------------------------------------------------------------------------
/02/readonly_doc.rb:
--------------------------------------------------------------------------------
1 | require '../common/document'
2 |
3 | class Document
4 | attr_accessor :read_only
5 | attr_reader :title, :author, :content
6 |
7 | # Much of the class omitted...
8 |
9 | def title=( new_title ) ##(main
10 | if not @read_only
11 | @title = new_title
12 | end
13 | end ##main)
14 |
15 | # Similar author= and content= methods omitted...
16 |
17 | end
18 |
--------------------------------------------------------------------------------
/02/readonly_doc_with_unless.rb:
--------------------------------------------------------------------------------
1 | require '../common/document'
2 |
3 | class Document
4 | attr_accessor :read_only
5 | attr_reader :title, :author, :content
6 |
7 | # Much of the class omitted...
8 |
9 | def title=( new_title ) ##(main
10 | unless @read_only
11 | @title = new_title
12 | end
13 | end ##main)
14 |
15 | # Similar author= and content= methods omitted...
16 |
17 | end
18 |
--------------------------------------------------------------------------------
/02/until.rb:
--------------------------------------------------------------------------------
1 | ##
2 |
3 | def until_loop( document )
4 | ##start
5 | until document.is_printed?
6 | document.print_next_page
7 | end
8 | ##end
9 | end
10 |
11 |
12 | end
13 |
--------------------------------------------------------------------------------
/02/while_not.rb:
--------------------------------------------------------------------------------
1 |
2 | def while_not( document )
3 | while ! document.is_printed? ##(main
4 | document.print_next_page
5 | end ##main)
6 | end
7 |
--------------------------------------------------------------------------------
/02/writable_doc.rb:
--------------------------------------------------------------------------------
1 | require '../common/document'
2 |
3 |
4 | class Document ##(main
5 | attr_accessor :writable
6 | attr_reader :title, :author, :content
7 |
8 | # Much of the class omitted...
9 |
10 | def title=( new_title )
11 | if @writable
12 | @title = new_title
13 | end
14 | end
15 |
16 | # Similar author= and content= methods omitted...
17 |
18 | end ##main)
19 |
--------------------------------------------------------------------------------
/03/2001.txt:
--------------------------------------------------------------------------------
1 | [:title, "2001"]
2 | [:genre, "sci fi"]
3 | [:rating, 10]
4 |
--------------------------------------------------------------------------------
/03/Rakefile:
--------------------------------------------------------------------------------
1 | require '../utils/tasks.rb'
2 |
--------------------------------------------------------------------------------
/03/add_authors_spec.rb:
--------------------------------------------------------------------------------
1 | require '../code/doc3'
2 |
3 | class Document ##(main
4 |
5 | # Most of the class omitted...
6 |
7 | def add_authors( names )
8 | @author += " #{names.join(' ')}"
9 | end
10 | end ##main)
11 |
12 |
13 | describe Document do
14 |
15 | it 'should work like the example says' do
16 | doc = Document.new( '', 'russ', '' )
17 | doc.add_authors( [ 'Strunk', 'White' ] ) ##+add
18 | doc.author.should == 'russ Strunk White'
19 | end
20 |
21 | end
22 |
--------------------------------------------------------------------------------
/03/add_authors_splat_spec.rb:
--------------------------------------------------------------------------------
1 | require '../code/doc3'
2 |
3 | class Document ##(main
4 |
5 | # Most of the class omitted...
6 |
7 | def add_authors( *names )
8 | @author += " #{names.join(' ')}"
9 | end
10 | end ##main)
11 |
12 |
13 | describe Document do
14 |
15 | it 'should work like the example says' do
16 | doc = Document.new( '', 'russ', '' )
17 | doc.add_authors( 'Strunk', 'White' ) ##+add
18 | doc.author.should == 'russ Strunk White'
19 | end
20 |
21 | end
22 |
--------------------------------------------------------------------------------
/03/bang.txt:
--------------------------------------------------------------------------------
1 | [3, 2, 1]
2 |
--------------------------------------------------------------------------------
/03/bang_spec.rb:
--------------------------------------------------------------------------------
1 | require '../utils/rspec_utils'
2 |
3 | describe 'the bang examples in the book' do
4 |
5 | it 'should have a good example of reverse and reverse!' do
6 | a = [ 1, 2, 3] ##(no_change
7 | a.reverse ##no_change)
8 |
9 | a.should == [ 1, 2, 3 ]
10 |
11 | out = output_of {
12 | pp a.reverse ##(print_both
13 | pp a ##print_both)
14 | }
15 |
16 | out.should match( /3.*2.*1.*1.*2.*3/m )
17 |
18 | File.write( 'reverse.txt', out )
19 |
20 | out = output_of {
21 | a.reverse! ##(print_bang
22 | pp a ##print_bang)
23 | }
24 |
25 | out.should match( /3.*2.*1/m )
26 |
27 | File.write( 'bang.txt', out )
28 | end
29 |
30 | end
31 |
--------------------------------------------------------------------------------
/03/dc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Spiderman
4 | Radioactive Spider
5 |
6 |
7 | Hulk
8 | Gamma Rays
9 |
10 |
11 | Reed Richards
12 | Cosmic Rays
13 |
14 |
15 |
--------------------------------------------------------------------------------
/03/delete.txt:
--------------------------------------------------------------------------------
1 | [0, -9, 5, 9]
2 |
--------------------------------------------------------------------------------
/03/ex_each_index_word_len.rb:
--------------------------------------------------------------------------------
1 | require '../code/doc3'
2 |
3 | class Document
4 | # A bit more idomatic, but not much ##(main
5 |
6 | def average_word_length
7 | total = 0.0
8 | words.each_index { |i| total += words[i].size }
9 | total / words.size
10 | end ##main)
11 | end
12 |
--------------------------------------------------------------------------------
/03/ex_each_word_len.rb:
--------------------------------------------------------------------------------
1 | require '../code/doc3'
2 |
3 | class Document ##(main
4 |
5 | # Most of the class omitted...
6 |
7 | def average_word_length
8 | total = 0.0
9 | words.each { |word| total += word.size }
10 |
11 | total / word_count
12 | end
13 | end ##main)
14 |
--------------------------------------------------------------------------------
/03/ex_for_word_len.rb:
--------------------------------------------------------------------------------
1 | require '../code/doc3'
2 |
3 | class Document
4 | # Not idiomatic at all! ##(main
5 |
6 | def average_word_length
7 | total = 0.0
8 |
9 | for i in 0...words.size
10 | total += words[i].size
11 | end
12 |
13 | total / words.size
14 | end ##main)
15 | end
16 |
--------------------------------------------------------------------------------
/03/ex_inject_word_len.rb:
--------------------------------------------------------------------------------
1 | require '../code/doc3'
2 |
3 | class Document
4 | def average_word_length ##(main
5 | total = words.inject(0.0){ |result, word| word.size + result}
6 | total / word_count
7 | end ##main)
8 | end
9 |
--------------------------------------------------------------------------------
/03/ex_map_inject_word_len.rb:
--------------------------------------------------------------------------------
1 | require '../code/doc3'
2 |
3 | class Document
4 | def average_word_length ##(main
5 | lengths = words.map { |word| word.size }
6 | len = lengths.inject { |total, word_size| word_size + total }
7 | len / words.size
8 | end ##main)
9 | end
10 |
--------------------------------------------------------------------------------
/03/ex_word_freq_doc.rb:
--------------------------------------------------------------------------------
1 | require '../code/doc3'
2 |
3 | class Document
4 | def word_frequencies ##(main
5 | freq = {}
6 | words.each do |word|
7 | if freq[word]
8 | freq[word] += 1
9 | else
10 | freq[word] = 1
11 | end
12 | end
13 | freq
14 | end ##main)
15 | end
16 |
--------------------------------------------------------------------------------
/03/index_for_each_index_spec.rb:
--------------------------------------------------------------------------------
1 | require '../code/doc3'
2 |
3 | class Document
4 | def index_for( word ) ##(main
5 | words.each_index do |i|
6 | return i if word == words[i]
7 | end
8 | nil
9 | end ##main)
10 | end
11 |
12 | describe "index_for method" do
13 | before :each do
14 | @doc = Document.new( 'title', 'author', 'the rain in spain')
15 | end
16 |
17 | it "should return the right word indexes" do
18 | @doc.index_for( 'the' ).should == 0
19 | @doc.index_for( 'rain' ).should == 1
20 | @doc.index_for( 'spain' ).should == 3
21 | end
22 | end
23 |
--------------------------------------------------------------------------------
/03/index_for_each_with_index_spec.rb:
--------------------------------------------------------------------------------
1 | require '../code/doc3'
2 |
3 | class Document
4 | def index_for( word ) ##(main
5 | words.each_with_index do |this_word, i|
6 | return i if this_word == word
7 | end
8 | nil
9 | end ##main)
10 | end
11 |
12 | describe "index_for method" do
13 | before :each do
14 | @doc = Document.new( 'title', 'author', 'the rain in spain')
15 | end
16 |
17 | it "should return the right word indexes" do
18 | @doc.index_for( 'the' ).should == 0
19 | @doc.index_for( 'rain' ).should == 1
20 | @doc.index_for( 'spain' ).should == 3
21 | end
22 | end
23 |
--------------------------------------------------------------------------------
/03/known_words.txt:
--------------------------------------------------------------------------------
1 | find_all
2 | sort
3 | sort!
4 | !
5 | push
6 | pop
7 | delete
8 | shift
9 | 'mom'
10 | SpecializedCollectionOfStuff
11 |
--------------------------------------------------------------------------------
/03/literal_spec.rb:
--------------------------------------------------------------------------------
1 | require '../utils/rspec_utils'
2 |
3 | describe 'the literal examples in the book' do
4 |
5 | it 'should have a good example of regular and percent w array lits' do
6 |
7 | poem_words = [ 'twinkle', 'little', 'star', 'how', 'I', 'wonder' ] ##+traditional
8 |
9 | old = poem_words
10 |
11 | poem_words = %w{ twinkle little star how I wonder } ##+percent_w
12 |
13 | old.should == poem_words
14 | end
15 |
16 | it 'should have a good example of old and new style hash lits' do
17 |
18 | freq = { "I" => 1, "don't" => 1, "like" => 1, "spam" => 963 } ##+string_keys
19 |
20 | book_info = { :first_name => 'Russ', :last_name => 'Olsen' } ##+sym_keys
21 |
22 | old = book_info
23 |
24 | book_info = { first_name: 'Russ', last_name: 'Olsen' } ##+quick_hash_keys
25 |
26 | old.should == book_info
27 | end
28 | end
29 |
--------------------------------------------------------------------------------
/03/load_font_spec.rb:
--------------------------------------------------------------------------------
1 | require '../code/doc3'
2 |
3 | def load_font( specification_hash ) ##(main
4 | # Load a font according to specification_hash[:name] etc.
5 | specification_hash ##--main
6 | end ##main)
7 |
8 | describe 'default hash behavior' do
9 |
10 | it 'should work like the example says' do
11 | result = (
12 | load_font( { :name => 'times roman', :size => 12 }) ##+paren_brace
13 | )
14 | result.should == { name: 'times roman', size: 12 }
15 |
16 | result = (
17 | load_font( :name => 'times roman', :size => 12 ) ##+paren
18 | )
19 | result.should == { name: 'times roman', size: 12 }
20 |
21 | result = (
22 | load_font :name => 'times roman', :size => 12 ##+nothing
23 | )
24 | result.should == { name: 'times roman', size: 12 }
25 |
26 | end
27 |
28 | end
29 |
--------------------------------------------------------------------------------
/03/map_inject_spec.rb:
--------------------------------------------------------------------------------
1 | require '../code/doc3'
2 | require '../utils/rspec_utils'
3 |
4 | describe "Various avg word size impls" do
5 |
6 | it "should return the right avg size with loop impl" do
7 | doc = Document.new( 'title', 'author', 'The Roots Of All Evil')
8 | lower_case_words = doc.words.map { |word| word.downcase } ##+downcase
9 | lower_case_words.should == %w{ the roots of all evil}
10 |
11 | out = output_of {
12 | pp doc.words.map { |word| word.size } ##+sizes
13 | lengths = doc.words.map { |word| word.size }
14 | lengths.should == [ 3, 5, 2, 3, 4 ]
15 | }
16 | File.write( 'sizes.txt', out )
17 | end
18 |
19 | end
20 |
--------------------------------------------------------------------------------
/03/new_find_spec.rb:
--------------------------------------------------------------------------------
1 | require '../code/doc3'
2 |
3 | class Document
4 | def index_for( word ) ##(main
5 | words.find_index { |this_word| word == this_word }
6 | end ##main)
7 | end
8 |
9 | describe "index_for method" do
10 | before :each do
11 | @doc = Document.new( 'title', 'author', 'the rain in spain')
12 | end
13 |
14 | it "should return the right word indexes" do
15 | @doc.index_for( 'the' ).should == 0
16 | @doc.index_for( 'rain' ).should == 1
17 | @doc.index_for( 'spain' ).should == 3
18 | end
19 | end
20 |
--------------------------------------------------------------------------------
/03/new_index_spec.rb:
--------------------------------------------------------------------------------
1 | require '../code/doc3'
2 |
3 | class Document
4 | def index_for( word ) ##(main
5 | i = 0
6 | words.each do |this_word|
7 | return i if word == this_word
8 | i += 1
9 | end
10 | nil
11 | end ##main)
12 | end
13 |
14 | describe "index_for method" do
15 | before :each do
16 | @doc = Document.new( 'title', 'author', 'the rain in spain')
17 | end
18 |
19 | it "should return the right word indexes" do
20 | @doc.index_for( 'the' ).should == 0
21 | @doc.index_for( 'rain' ).should == 1
22 | @doc.index_for( 'spain' ).should == 3
23 | end
24 | end
25 |
--------------------------------------------------------------------------------
/03/order.txt:
--------------------------------------------------------------------------------
1 | [:first, "mama"]
2 | [:second, "papa"]
3 | [:third, "baby"]
4 |
--------------------------------------------------------------------------------
/03/order_spec.rb:
--------------------------------------------------------------------------------
1 | require '../utils/rspec_utils'
2 |
3 | describe 'the ordered hash examples in the book' do
4 |
5 | it 'should have a good example of how hashes are ordered' do
6 | hey_its_ordered = { first: 'mama', second: 'papa', third: 'baby' } ##+hey_order
7 |
8 | out = output_of {
9 | hey_its_ordered.each { |entry| pp entry } ##+then_iterate
10 | }
11 |
12 | out.should match( /first.*second.*third/m )
13 | File.write( 'order.txt', out )
14 |
15 | hey_its_ordered[:fourth] = 'grandma' ##+add_grandma
16 |
17 | out = output_of { pp hey_its_ordered }
18 | out.should match( /first.*second.*third.*fourth/m )
19 |
20 | hey_its_ordered[:first] = 'mom'
21 |
22 | out = output_of { pp hey_its_ordered }
23 | out.should match( /first.*second.*third.*fourth/m )
24 | end
25 | end
26 |
--------------------------------------------------------------------------------
/03/reverse.txt:
--------------------------------------------------------------------------------
1 | [3, 2, 1]
2 | [1, 2, 3]
3 |
--------------------------------------------------------------------------------
/03/sizes.txt:
--------------------------------------------------------------------------------
1 | [3, 5, 2, 3, 4]
2 |
--------------------------------------------------------------------------------
/03/superhero.txt:
--------------------------------------------------------------------------------
1 | {"super-hero"=>
2 | [{"name"=>["Spiderman"], "origin"=>["Radioactive Spider"]},
3 | {"name"=>["Hulk"], "origin"=>["Gamma Rays"]},
4 | {"name"=>["Reed Richards"], "origin"=>["Cosmic Rays"]}]}
5 |
--------------------------------------------------------------------------------
/03/twinkle.txt:
--------------------------------------------------------------------------------
1 | ["twinkle", 2]
2 | ["little", 1]
3 | ["star", 1]
4 |
--------------------------------------------------------------------------------
/03/xmlsimple_spec.rb:
--------------------------------------------------------------------------------
1 | require '../utils/rspec_utils'
2 |
3 | describe 'xmlsimple' do
4 |
5 | it 'should work like the book says' do
6 | require 'xmlsimple' ##(main
7 | data = XmlSimple.xml_in('dc.xml') ##main)
8 |
9 | data.instance_of?(Hash).should == true
10 |
11 | out = output_of { pp data }
12 | out.should match(/"super-hero".*name.*"Spiderman"/m)
13 | File.write( "superhero.txt", out )
14 |
15 | end
16 | end
17 |
--------------------------------------------------------------------------------
/04/Rakefile:
--------------------------------------------------------------------------------
1 | require '../utils/tasks.rb'
2 |
--------------------------------------------------------------------------------
/04/bytes.txt:
--------------------------------------------------------------------------------
1 | 67
2 | 108
3 | 97
4 | 114
5 | 107
6 | 101
7 |
--------------------------------------------------------------------------------
/04/clarke.txt:
--------------------------------------------------------------------------------
1 | C
2 | l
3 | a
4 | r
5 | k
6 | e
7 |
--------------------------------------------------------------------------------
/04/mars.txt:
--------------------------------------------------------------------------------
1 | Mars is written by Ben Bova
2 |
--------------------------------------------------------------------------------
/04/sub.txt:
--------------------------------------------------------------------------------
1 | no yes
2 | no no
3 |
--------------------------------------------------------------------------------
/05/Rakefile:
--------------------------------------------------------------------------------
1 | require '../utils/tasks.rb'
2 |
--------------------------------------------------------------------------------
/05/first_date.txt:
--------------------------------------------------------------------------------
1 | 0
2 |
--------------------------------------------------------------------------------
/05/mars.txt:
--------------------------------------------------------------------------------
1 | Mars is written by Ben Bova
2 |
--------------------------------------------------------------------------------
/05/scanning.txt:
--------------------------------------------------------------------------------
1 | 6
2 |
--------------------------------------------------------------------------------
/06/Rakefile:
--------------------------------------------------------------------------------
1 | require '../utils/tasks.rb'
2 |
--------------------------------------------------------------------------------
/06/add.rb:
--------------------------------------------------------------------------------
1 | def add( a, b )
2 | a + b
3 | end
4 |
--------------------------------------------------------------------------------
/06/ex_demo.rb:
--------------------------------------------------------------------------------
1 | ##
2 |
3 | ##start ex1
4 | this is the only line of ex1
5 | ##end
6 |
7 | ##start ex2
8 | this is the first of 3
9 | 2nd
10 | third of 3
11 | ##end
12 |
--------------------------------------------------------------------------------
/06/ex_demo_ex1.rb:
--------------------------------------------------------------------------------
1 | this is the only line of ex1
2 |
--------------------------------------------------------------------------------
/06/ex_demo_ex2.rb:
--------------------------------------------------------------------------------
1 | this is the first of 3
2 | 2nd
3 | third of 3
4 |
--------------------------------------------------------------------------------
/06/known_words.txt:
--------------------------------------------------------------------------------
1 | HashWithIndifferentAccess
2 | documents
3 | 0x29ef
4 | 0
5 | -1
6 | 'l'
7 |
--------------------------------------------------------------------------------
/07/Rakefile:
--------------------------------------------------------------------------------
1 | require '../utils/tasks.rb'
2 |
--------------------------------------------------------------------------------
/07/custom_to_s.txt:
--------------------------------------------------------------------------------
1 | Document: Emma by Austin
2 |
--------------------------------------------------------------------------------
/07/ex_11_spec.rb:
--------------------------------------------------------------------------------
1 | require '../code/document.rb'
2 | require '../utils/rspec_utils'
3 |
4 | class Person ##(person
5 | attr_accessor :salary # A method call
6 | attr_reader :name # Another method call
7 | attr_writer :password # And another
8 | end ##person)
9 |
10 |
11 | describe 'chapter' do
12 | it 'should have good examples of suprising methods' do
13 | require 'date' # A Call to a method ##+req_date
14 | end
15 |
16 | it 'should have a working person class' do
17 | p = Person.new
18 | p.salary = 100
19 | p.name.should == nil
20 | p.password = 'xyzzy'
21 | end
22 | end
23 |
--------------------------------------------------------------------------------
/07/ex_12_spec.rb:
--------------------------------------------------------------------------------
1 | require '../code/document.rb'
2 | require '../utils/rspec_utils'
3 |
4 | class Document ##(main
5 | # Most of the class omitted...
6 |
7 | # Send this document to off via email
8 | def send( recipient )
9 | # Do some interesting SMTP stuff...
10 | "my send" ##--main
11 | end
12 | end ##main)
13 |
14 | describe 'chapter' do
15 | it 'should have a good override send example' do
16 | doc = Document.new( 'Ethics', 'Spinoza', 'By that which is' )
17 | doc.send('russ@russolsen.com').should == 'my send'
18 | end
19 | end
20 |
--------------------------------------------------------------------------------
/07/ex_13_spec.rb:
--------------------------------------------------------------------------------
1 | require '../code/document.rb'
2 | require '../utils/rspec_utils'
3 |
4 | class Document ##(main
5 | # Mostly omitted...
6 |
7 | def to_s
8 | "#{title} by #{aothor}" # oops!
9 | end
10 | end ##main)
11 |
12 | describe 'chapter' do
13 | it 'should have a good example of a bad to_s' do
14 | lambda {
15 | doc = Document.new( 'Ethics', 'Spinoza', 'By that which is...' )
16 | doc.to_s
17 | }.should raise_error
18 | end
19 | end
20 |
--------------------------------------------------------------------------------
/07/ex_1_spec.rb:
--------------------------------------------------------------------------------
1 |
2 | require '../code/document.rb'
3 |
4 | class Document ##(main
5 |
6 | # Most of the class omitted...
7 |
8 | # A method
9 |
10 | def words
11 | @content.split
12 | end
13 |
14 | # And another one
15 |
16 | def word_count
17 | words.size
18 | end
19 | end ##main)
20 |
21 | describe 'chapter' do
22 | it 'should have a good document example' do
23 | doc = Document.new( 'Ethics', 'Spinoza', 'By that which is...' ) ##+make_doc
24 | doc.words.should == %w{ By that which is... }
25 | (
26 | doc.word_count ##+get_word_count
27 | ).should == 4
28 | end
29 | end
30 |
--------------------------------------------------------------------------------
/07/ex_2_spec.rb:
--------------------------------------------------------------------------------
1 | require '../code/doc3.rb'
2 | require '../utils/rspec_utils'
3 |
4 | class Document ##(main
5 | # Most of the class on holiday...
6 |
7 | def about_me
8 | puts "I am #{self}"
9 | puts "My title is #{self.title}"
10 | puts "I have #{self.word_count} words"
11 | end
12 | end ##main)
13 |
14 | describe 'chapter' do
15 | it 'should have a good about_me example' do
16 | doc = Document.new( 'Ethics', 'Spinoza', 'By that which is...' )
17 | out = output_of { doc.about_me }
18 | out.should match( /I am.*My title is Ethics.*4 words/m )
19 | File.write( "about_me.txt", out )
20 | end
21 | end
22 |
--------------------------------------------------------------------------------
/07/ex_3_spec.rb:
--------------------------------------------------------------------------------
1 | require '../code/document.rb'
2 | require '../utils/rspec_utils'
3 |
4 | # RomanceNovel is a subclass of Document, ##(main
5 | # which is a subclass of Object
6 |
7 | class RomanceNovel < Document
8 | # Lot's of steamy stuff omitted...
9 | end ##main)
10 |
11 | describe 'chapter' do
12 | it 'should have a good about_me example' do
13 | doc = RomanceNovel.new( 'Ethics', 'Spinoza', 'By that which is...' )
14 | end
15 | end
16 |
--------------------------------------------------------------------------------
/07/ex_4_spec.rb:
--------------------------------------------------------------------------------
1 | require '../code/document.rb'
2 | require '../utils/rspec_utils'
3 |
4 | describe 'chapter' do
5 | it 'should have a good everything is an object examples' do
6 | (
7 | -3.abs # Returns 3 ##+abs_example
8 | ).should == 3
9 |
10 | # Call some methods on some objects ##(various_examples
11 |
12 | "abc".upcase
13 | :abc.length
14 | /abc/.class ##various_examples)
15 |
16 |
17 | # Call some methods on a couple of familiar objects ##(truefalse_examples
18 |
19 | true.class # Returns Trueclass
20 | false.nil? # False is close, but not nil ##truefalse_examples)
21 |
22 | (
23 | true.class.class # Returns Class ##+true_class_example
24 | ).should == Class
25 |
26 | nil.class # Returns NilClass ##(nil_class_example
27 | nil.nil? # Yes, finally true! ##nil_class_example)
28 | end
29 | end
30 |
--------------------------------------------------------------------------------
/07/ex_5_spec.rb:
--------------------------------------------------------------------------------
1 | require '../code/document.rb'
2 | require '../utils/rspec_utils'
3 |
4 | describe 'chapter' do
5 | it 'should have a good default to_s example' do
6 | out = output_of {
7 | doc = Document.new( 'Emma', 'Austin', 'Emma Woodhouse, ...' ) ##(default_to_s
8 | puts doc ##default_to_s)
9 | }
10 | out.should match( / "
3 | cmd = gets
4 | puts( eval( cmd ) )
5 | end
6 |
--------------------------------------------------------------------------------
/07/print_word_count.txt:
--------------------------------------------------------------------------------
1 | The number of words is 4
2 |
--------------------------------------------------------------------------------
/07/variables.txt:
--------------------------------------------------------------------------------
1 | [:@title, :@author, :@content]
2 |
--------------------------------------------------------------------------------
/08/Rakefile:
--------------------------------------------------------------------------------
1 | require '../utils/tasks.rb'
2 |
--------------------------------------------------------------------------------
/08/cryptic_spec.rb:
--------------------------------------------------------------------------------
1 |
2 | require '../code/simple_doc'
3 |
4 | class Doc ##(cryptic
5 | attr_accessor :ttl, :au, :c
6 |
7 | def initialize(ttl, au, c)
8 | @ttl = ttl; @au = au; @c = c
9 | end
10 |
11 | def wds; @c.split; end
12 | end ##cryptic)
13 |
14 | describe Doc do
15 | before :each do
16 | @doc = Doc.new( 'Title', 'Russ', 'hello world' )
17 | end
18 |
19 | it 'should keep the title author and content' do
20 | @doc.ttl.should == 'Title'
21 | @doc.au.should == 'Russ'
22 | @doc.c.should == 'hello world'
23 | end
24 |
25 | it 'should return the words in the doc' do
26 | @doc.wds[0].should == 'hello'
27 | @doc.wds[1].should == 'world'
28 | end
29 |
30 | end
31 |
--------------------------------------------------------------------------------
/08/desc_doc.rb:
--------------------------------------------------------------------------------
1 | require '../code/simple_doc.rb'
2 |
3 | class Document ##(main
4 | # Most of the class omitted...
5 |
6 | def description
7 | "#{@title.long_name} by #{@author.last_name}"
8 | end
9 | end ##main)
10 |
11 |
--------------------------------------------------------------------------------
/08/desc_doc_spec.rb:
--------------------------------------------------------------------------------
1 | require 'pp'
2 | require "desc_doc"
3 | require 'title_author'
4 |
5 | describe Document do
6 | before :each do
7 | @title = Title.new( 'Long', 'lg', '123')
8 | @author = Author.new( 'Bob', 'Smith' )
9 | @doc = Document.new( @title, @author, 'hello' )
10 | end
11 |
12 | it "should hold onto title and author" do
13 | @doc.title.long_name.should == 'Long'
14 | @doc.title.short_name.should == 'lg'
15 | @doc.title.isbn.should == '123'
16 | @doc.author.first_name.should == 'Bob'
17 | @doc.author.last_name.should == 'Smith'
18 | end
19 |
20 | it 'should have a working description' do
21 | @doc.description.should == 'Long by Smith'
22 | end
23 |
24 | end
25 |
--------------------------------------------------------------------------------
/08/ex_title_author_spec.rb:
--------------------------------------------------------------------------------
1 | require 'ex_lazy_document'
2 | require 'title_author'
3 |
4 | describe Title do
5 | it "should hold onto its attributes" do
6 | t = Title.new( 'dick and jane', 'd&j', '1234')
7 | t.long_name.should == 'dick and jane'
8 | t.short_name.should == 'd&j'
9 | t.isbn.should == '1234'
10 | end
11 | end
12 |
13 | describe Author do
14 | it "should hold onto its attributes" do
15 | a = Author.new( 'russ', 'olsen' )
16 | a.first_name.should == 'russ'
17 | a.last_name.should == 'olsen'
18 | end
19 |
20 | it "should look like example in book" do
21 |
22 | two_cities = Title.new( 'A Tale Of Two Cities', ##(2cities
23 | '2 Cities', '0-999-99999-9' )
24 | dickens = Author.new( 'Charles', 'Dickens' )
25 | doc = Document.new( two_cities, dickens, 'It was the best...' ) ##2cities)
26 |
27 | two_cities.long_name.should == 'A Tale Of Two Cities'
28 | end
29 | end
30 |
--------------------------------------------------------------------------------
/08/example.txt:
--------------------------------------------------------------------------------
1 | a
2 | a
3 | a
4 |
--------------------------------------------------------------------------------
/08/gutted_doc.rb:
--------------------------------------------------------------------------------
1 | class Document
2 | # Body of the class unchanged...
3 | end
4 |
5 | class LazyDocument
6 | # Body of the class unchanged...
7 | end
8 |
--------------------------------------------------------------------------------
/08/gutted_doc_spec.rb:
--------------------------------------------------------------------------------
1 | require 'pp'
2 | require "#{File.dirname(__FILE__)}/gutted_doc"
3 |
4 | describe Document do
5 | it "should be a class" do
6 | Document.class.should == Class
7 | doc = Document.new
8 | end
9 | end
10 |
11 | describe LazyDocument do
12 | it "should be a class" do
13 | LazyDocument.class.should === Class
14 | doc = LazyDocument.new
15 | end
16 | end
17 |
--------------------------------------------------------------------------------
/08/longer2_spec.rb:
--------------------------------------------------------------------------------
1 |
2 | require '../code/simple_doc'
3 |
4 | class Document
5 | def is_longer_than?( number_of_characters ) ##(longer
6 | @content.length > number_of_characters
7 | end ##longer)
8 | end
9 |
10 | describe "is longer than" do
11 | it 'return true if arg is bigger than size' do
12 | doc = Document.new( 'a doc', 'russ', 'abc' )
13 | doc.is_longer_than?( 1 ).should == true
14 | doc.is_longer_than?( 2 ).should == true
15 | doc.is_longer_than?( 3 ).should == false
16 | doc.is_longer_than?( 4 ).should == false
17 | doc.is_longer_than?( 999 ).should == false
18 | end
19 |
20 | end
21 |
--------------------------------------------------------------------------------
/08/longer3_spec.rb:
--------------------------------------------------------------------------------
1 |
2 | require '../code/simple_doc'
3 |
4 | class Document
5 | # Given a number, which needs to be an instance of Numeric, ##(longer
6 | # return true if the number of characters in the document
7 | # exceeds the number.
8 | def is_longer_than?( number_of_characters )
9 | @content.length > number_of_characters
10 | end ##longer)
11 | end
12 |
13 | describe "is longer than" do
14 | it 'return true if arg is bigger than size' do
15 | doc = Document.new( 'a doc', 'russ', 'abc' )
16 | doc.is_longer_than?( 1 ).should == true
17 | doc.is_longer_than?( 2 ).should == true
18 | doc.is_longer_than?( 3 ).should == false
19 | doc.is_longer_than?( 4 ).should == false
20 | doc.is_longer_than?( 999 ).should == false
21 | end
22 |
23 | end
24 |
--------------------------------------------------------------------------------
/08/longer_spec.rb:
--------------------------------------------------------------------------------
1 |
2 | require '../code/simple_doc'
3 |
4 | class Document
5 | def is_longer_than?( n ) ##(longer
6 | @content.length > n
7 | end ##longer)
8 | end
9 |
10 | describe "is longer than" do
11 | it 'return true if arg is bigger than size' do
12 | doc = Document.new( 'a doc', 'russ', 'abc' )
13 | doc.is_longer_than?( 1 ).should == true
14 | doc.is_longer_than?( 2 ).should == true
15 | doc.is_longer_than?( 3 ).should == false
16 | doc.is_longer_than?( 4 ).should == false
17 | doc.is_longer_than?( 999 ).should == false
18 | end
19 |
20 | end
21 |
--------------------------------------------------------------------------------
/08/title_author.rb:
--------------------------------------------------------------------------------
1 | class Title
2 | attr_reader :long_name, :short_name
3 | attr_reader :isbn
4 |
5 | def initialize(long_name, short_name, isbn)
6 | @long_name = long_name
7 | @short_name = short_name
8 | @isbn = isbn
9 | end
10 | end
11 |
12 | class Author
13 | attr_reader :first_name, :last_name
14 |
15 | def initialize( first_name, last_name )
16 | @first_name = first_name
17 | @last_name = last_name
18 | end
19 | end
20 |
--------------------------------------------------------------------------------
/08/type_check_spec.rb:
--------------------------------------------------------------------------------
1 |
2 | require '../code/simple_doc'
3 |
4 | class Document
5 | def initialize( title, author, content ) ##(bad_type
6 | raise "title isn't a String" unless title.kind_of? String
7 | raise "author isn't a String" unless author.kind_of? String
8 | raise "content isn't a String" unless content.kind_of? String
9 | @title = title
10 | @author = author
11 | @content = content
12 | end ##bad_type)
13 | end
14 |
15 | describe "bad type checking" do
16 | it 'should throw and error if the title isnt a string' do
17 | lambda { doc = Document.new( 1, "", "" )}.should raise_error(RuntimeError)
18 | end
19 |
20 | it 'should throw and error if the author isnt a string' do
21 | lambda { doc = Document.new( "", 1, "" )}.should raise_error(RuntimeError)
22 | end
23 |
24 | it 'should throw and error if the content isnt a string' do
25 | lambda { doc = Document.new( "", "", 1 )}.should raise_error(RuntimeError)
26 | end
27 | end
28 |
--------------------------------------------------------------------------------
/08/wild_spec.rb:
--------------------------------------------------------------------------------
1 |
2 |
3 | describe "in the wild examples" do
4 |
5 | it "should have a good file open example" do
6 | open_file = File.open( '/etc/passwd' ) ##+open
7 | open_file.close
8 | end
9 |
10 | it 'should have a good stringio example' do
11 | require 'stringio' ##(sio
12 | open_string = StringIO.new( "So say we all!\nSo say we all!\n" ) ##sio)
13 | end
14 |
15 | it 'should have a good set example' do
16 | require 'set'
17 | five_even = [ 2, 4, 6, 8, 10 ] ##(set
18 | five_even_set = Set.new( five_even ) ##set)
19 | five_even_set.size.should == 5
20 | end
21 | end
22 |
--------------------------------------------------------------------------------
/09/Rakefile:
--------------------------------------------------------------------------------
1 | require '../utils/tasks.rb'
2 |
--------------------------------------------------------------------------------
/09/array_spec.rb:
--------------------------------------------------------------------------------
1 | describe "Array#each" do
2 | it "yields each element to the block" do
3 | a = []
4 | x = [1, 2, 3]
5 | x.each { |item| a << item }.should equal(x)
6 | a.should == [1, 2, 3]
7 | end
8 |
9 | # Lots of stuff omitted
10 | end
11 |
--------------------------------------------------------------------------------
/09/doc_spec.cmd:
--------------------------------------------------------------------------------
1 | rspec document_spec.rb
2 |
--------------------------------------------------------------------------------
/09/document.rb:
--------------------------------------------------------------------------------
1 | require '../code/doc3'
2 |
--------------------------------------------------------------------------------
/09/document2_spec.rb:
--------------------------------------------------------------------------------
1 | require '../code/doc3'
2 |
3 | describe Document do
4 | it 'should hold on to the contents' do
5 | text = 'A bunch of words'
6 | doc = Document.new( 'test', 'nobody', text )
7 | doc.content.should == text
8 | end
9 |
10 | it 'should return all of the words in the document' do
11 | text = 'A bunch of words'
12 | doc = Document.new( 'test', 'nobody', text )
13 | doc.content.should match( /A bunch.*/ )
14 | doc.words.include?( 'bunch' ).should == true ##+simple_should
15 | doc.words.should include( 'bunch' ) ##+should_include
16 | doc.words.should include( 'of' )
17 | doc.words.should include( 'words' )
18 | doc.words.should_not include( 'Excelsior' )
19 | end
20 |
21 | it 'should know how many words it contains' do
22 | text = 'A bunch of words'
23 | doc = Document.new( 'test', 'nobody', text )
24 | doc.word_count.should == 4
25 | end
26 |
27 | end
28 |
--------------------------------------------------------------------------------
/09/document_spec.rb:
--------------------------------------------------------------------------------
1 | require '../code/doc3'
2 |
3 | describe Document do ##(main
4 | it 'should hold on to the contents' do
5 | text = 'A bunch of words'
6 | doc = Document.new( 'test', 'nobody', text )
7 | doc.content.should == text
8 | end
9 |
10 | it 'should return all of the words in the document' do
11 | text = 'A bunch of words'
12 | doc = Document.new( 'test', 'nobody', text )
13 | doc.words.include?( 'A' ).should == true
14 | doc.words.include?( 'bunch' ).should == true
15 | doc.words.include?( 'of' ).should == true
16 | doc.words.include?( 'words' ).should == true
17 | end
18 |
19 | it 'should know how many words it contains' do
20 | text = 'A bunch of words'
21 | doc = Document.new( 'test', 'nobody', text )
22 | doc.word_count.should == 4
23 | end
24 | end ##main)
25 |
--------------------------------------------------------------------------------
/09/ex_assertion_test.rb:
--------------------------------------------------------------------------------
1 | require 'test/unit'
2 | require '../code/doc3'
3 |
4 |
5 | class DocumentTest < Test::Unit::TestCase
6 |
7 | def test_assert_match
8 | assert_match /times.*/, 'times new roman' ##+match
9 | end
10 |
11 | def test_instance_of
12 | assert_instance_of String, 'hello' ##+instance
13 | end
14 |
15 | def test_raise
16 | assert_raise ZeroDivisionError do ##(with_raise
17 | x = 1/0
18 | end ##with_raise)
19 | end
20 |
21 | def test_no_raise
22 | assert_nothing_thrown do ##(no_raise
23 | x = 1/2
24 | end ##no_raise)
25 | end
26 |
27 | end
28 |
--------------------------------------------------------------------------------
/09/ex_bad_test_spec.rb:
--------------------------------------------------------------------------------
1 | describe 'a bad test' do
2 |
3 | before :each do
4 | @message = 'error error error'
5 | end
6 |
7 | # This test should was meant to fail, but doesn't
8 |
9 | it 'should not have an error message' do
10 | found_error = @message =~ /error/
11 | found_error.should_not == true
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/09/ex_document_test.rb:
--------------------------------------------------------------------------------
1 | require 'pp'
2 | require 'test/unit' ##(main
3 | require 'document.rb'
4 |
5 | class DocumentTest < Test::Unit::TestCase
6 | def test_document_holds_onto_contents ##(one_method
7 | text = 'A bunch of words'
8 | doc = Document.new('test', 'nobody', text)
9 | assert_equal text, doc.content, 'Contents are still there' ##+with_comment
10 | end ##one_method)
11 |
12 | def test_that_doc_can_return_words_in_array
13 | text = 'A bunch of words'
14 | doc = Document.new('test', 'nobody', text)
15 | assert doc.words.include?( 'A' )
16 | assert doc.words.include?( 'bunch' ) ##+plain_assert
17 | assert doc.words.include?( 'of' )
18 | assert doc.words.include?( 'words' )
19 | end
20 |
21 | def test_that_word_count_is_correct
22 | text = 'A bunch of words'
23 | doc = Document.new('test', 'nobody', text)
24 | assert_equal 4, doc.word_count, 'Word count is correct'
25 | end
26 | end ##main)
27 |
--------------------------------------------------------------------------------
/09/ex_longstring_spec.rb:
--------------------------------------------------------------------------------
1 | describe 'stubbing an apparently long string' do
2 |
3 | it 'should know how to make a string look long' do
4 |
5 | apparently_long_string = 'actually short' ##(main
6 | apparently_long_string.stub!( :length ).and_return( 1000000 ) ##main)
7 |
8 | apparently_long_string.should == 'actually short'
9 | apparently_long_string.length.should == 1000000
10 | end
11 |
12 | end
13 |
--------------------------------------------------------------------------------
/09/ex_mock_spec.rb:
--------------------------------------------------------------------------------
1 | describe 'mocking with rspec' do
2 | before :each do
3 | @doc = mock
4 | @doc.should_receive(:check_spelling).and_return('correct')
5 | end
6 |
7 | it 'should know how to print itself' do ##(main
8 | mock_printer = mock('Printer')
9 | mock_printer.should_receive(:available?).and_return(true)
10 | mock_printer.should_receive(:render).exactly(3).times
11 | @doc.check_spelling( mock_printer ).should == 'correct' ##main)
12 |
13 | @doc = mock
14 | mock_printer.available?.should == true
15 | 3.times { mock_printer.render }
16 | end ##+main
17 | end
18 |
19 |
--------------------------------------------------------------------------------
/09/ex_printable_document.rb:
--------------------------------------------------------------------------------
1 | require 'document'
2 |
3 | class PrintableDocument < Document ##(main
4 | def print( printer )
5 | return 'Printer unavailable' unless printer.available?
6 | printer.render( "#{title}\n" )
7 | printer.render( "By #{author}\n" )
8 | printer.render( content )
9 | 'Done'
10 | end
11 | end ##main)
12 |
--------------------------------------------------------------------------------
/09/ex_printable_document_spec.rb:
--------------------------------------------------------------------------------
1 | require 'ex_printable_document'
2 |
3 | describe PrintableDocument do ##(main
4 | before :each do
5 | @text = 'A bunch of words'
6 | @doc = PrintableDocument.new( 'test', 'nobody', @text )
7 | end
8 |
9 | it 'should know how to print itself' do
10 | stub_printer = stub :available? => true, :render => nil ##+stub_printer
11 | @doc.print( stub_printer ).should == 'Done'
12 | end
13 |
14 | it 'should return the proper string if printer is offline' do
15 | stub_printer = stub :available? => false, :render => nil
16 | @doc.print( stub_printer ).should == 'Printer unavailable'
17 | end
18 | end ##main)
19 |
--------------------------------------------------------------------------------
/09/ex_run_document_spec.rb:
--------------------------------------------------------------------------------
1 | require '../utils/rspec_utils'
2 |
3 | describe 'running the document spec' do
4 | it 'should work like described in the book' do
5 | cmd = "`#{File.read( "doc_spec.cmd" )}`"
6 | out = eval cmd
7 | out.should match( /\.\..*Finished/m )
8 | File.write( 'run_spec.txt', out )
9 | end
10 | end
11 |
--------------------------------------------------------------------------------
/09/ex_run_tests_spec.rb:
--------------------------------------------------------------------------------
1 | describe 'unit tests' do
2 | it 'should pass when you run it' do
3 | Dir['*_test.rb'].sort.each do |test_file|
4 | puts test_file
5 | puts ">> #{test_file}"
6 | system("ruby -I . #{test_file}").should == true
7 | end
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/09/ex_shoulda_test.rb:
--------------------------------------------------------------------------------
1 | require 'test/unit'
2 | require 'shoulda'
3 | require 'document.rb'
4 |
5 | class DocumentTest < Test::Unit::TestCase
6 | context 'A basic document class' do
7 | def setup
8 | @text = 'A bunch of words'
9 | @doc = Document.new('a test', 'russ', @text)
10 | end
11 |
12 | should 'hold on to the contents' do
13 | assert_equal @text, @doc.content, 'Contents still there'
14 | end
15 |
16 | # Rest of the test omitted...
17 | end
18 | end
19 |
--------------------------------------------------------------------------------
/09/ex_simple_spec.rb:
--------------------------------------------------------------------------------
1 | require '../code/doc3'
2 |
3 | describe Document do ##(main
4 | it 'should not catch fire when you create an instance' do
5 | Document.new( 'title', 'author', 'stuff' ).should_not == nil
6 | end
7 | end ##main)
8 |
--------------------------------------------------------------------------------
/09/ex_starter_test.rb:
--------------------------------------------------------------------------------
1 | require 'pp'
2 | require 'test/unit'
3 | require 'document.rb'
4 |
5 | class DocumentTest < Test::Unit::TestCase
6 | def test_document_holds_onto_contents ##(one_method
7 | text = 'A bunch of words'
8 | doc = Document.new('test', 'nobody', text)
9 | assert_equal text, doc.content
10 | end ##one_method)
11 | end
12 |
--------------------------------------------------------------------------------
/09/if_spec.rb:
--------------------------------------------------------------------------------
1 | describe "The if expression" do
2 | it "evaluates body if expression is true" do
3 | a = []
4 | if true
5 | a << 123
6 | end
7 | a.should == [123]
8 | end
9 |
10 | it "does not evaluate body if expression is false" do
11 | a = []
12 | if false
13 | a << 123
14 | end
15 | a.should == []
16 | end
17 |
18 | # Lots and lots of stuff omitted
19 | end
20 |
--------------------------------------------------------------------------------
/09/known_words.txt:
--------------------------------------------------------------------------------
1 | assert
2 | assert_equal
3 | assert_nil
4 | assert_not_equal
5 | assert_not_nil
6 | test_that_it_works
7 | test_number_four
8 | teardown
9 | after
10 |
--------------------------------------------------------------------------------
/09/readable_document_spec.rb:
--------------------------------------------------------------------------------
1 | require 'document' ##(main
2 |
3 | describe Document do
4 | before :each do
5 | @text = 'A bunch of words'
6 | @doc = Document.new( 'test', 'nobody', @text )
7 | end
8 |
9 | it 'should hold on to the contents' do
10 | @doc.content.should == @text
11 | end
12 |
13 | it 'should know which words it has' do
14 | @doc.words.should include( 'A' )
15 | @doc.words.should include( 'bunch' )
16 | @doc.words.should include( 'of' )
17 | @doc.words.should include( 'words' )
18 | end
19 |
20 | it 'should know how many words it contains' do
21 | @doc.word_count.should == 4
22 | end
23 |
24 | end ##main)
25 |
--------------------------------------------------------------------------------
/09/tidy_document_test.rb:
--------------------------------------------------------------------------------
1 | require 'document.rb'
2 | require 'test/unit'
3 |
4 | class DocumentTest < Test::Unit::TestCase ##(main
5 | def setup
6 | @text = 'A bunch of words'
7 | @doc = Document.new('test', 'nobody', @text)
8 | end
9 |
10 | def test_that_document_holds_onto_contents
11 | assert_equal @text, @doc.content, 'Contents are still there'
12 | end
13 |
14 | def test_that_doc_can_return_words_in_array
15 | assert @doc.words.include?( 'A' )
16 | assert @doc.words.include?( 'bunch' )
17 | assert @doc.words.include?( 'of' )
18 | assert @doc.words.include?( 'words' )
19 | end
20 |
21 | def test_that_word_count_is_correct
22 | assert_equal 4, @doc.word_count, 'Word count is correct'
23 | end
24 | end ##main)
25 |
--------------------------------------------------------------------------------
/10/Rakefile:
--------------------------------------------------------------------------------
1 | require '../utils/tasks.rb'
2 |
--------------------------------------------------------------------------------
/10/compressor1.rb:
--------------------------------------------------------------------------------
1 | class TextCompressor
2 | attr_reader :unique, :index
3 |
4 | def initialize( text )
5 | @unique = []
6 | @index = []
7 |
8 | words = text.split
9 | words.each do |word|
10 | i = @unique.index( word )
11 | if i
12 | @index << i
13 | else
14 | @unique << word
15 | @index << unique.size - 1
16 | end
17 | end
18 | end
19 | end
20 |
--------------------------------------------------------------------------------
/10/compressor1_spec.rb:
--------------------------------------------------------------------------------
1 | require 'compressor1'
2 | require 'compressor_examples'
3 |
4 |
5 | describe "Examples int he book" do
6 | it 'should match the example' do
7 | text = "This specification is the spec for a specification" ##(make
8 | compressor = TextCompressor.new( text ) ##make)
9 |
10 | unique_word_array = compressor.unique ##(use
11 | word_index = compressor.index ##use)
12 |
13 | unique_word_array.class.should == Array
14 | word_index.class.should == Array
15 | unique_word_array[word_index[0]].should == 'This'
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/10/compressor2.rb:
--------------------------------------------------------------------------------
1 |
2 | class TextCompressor
3 | attr_reader :unique, :index
4 |
5 | def initialize( text )
6 | @unique = []
7 | @index = []
8 |
9 | words = text.split
10 | words.each do |word|
11 | i = unique_index_of( word )
12 | if i
13 | @index << i
14 | else
15 | @index << add_unique_word( word )
16 | end
17 | end
18 | end
19 |
20 | def unique_index_of( word )
21 | @unique.index(word)
22 | end
23 |
24 | def add_unique_word( word )
25 | @unique << word
26 | unique.size - 1
27 | end
28 | end
29 |
--------------------------------------------------------------------------------
/10/compressor2_spec.rb:
--------------------------------------------------------------------------------
1 | require 'compressor2'
2 | require 'compressor_examples'
3 |
--------------------------------------------------------------------------------
/10/compressor3.rb:
--------------------------------------------------------------------------------
1 |
2 | class TextCompressor
3 | attr_reader :unique, :index
4 |
5 | def initialize( text )
6 | @unique = []
7 | @index = []
8 | add_text( text )
9 | end
10 |
11 | def add_text( text )
12 | words = text.split
13 | words.each { |word| add_word( word ) }
14 | end
15 |
16 | def add_word( word )
17 | i = unique_index_of( word ) || add_unique_word( word )
18 | @index << i
19 | end
20 |
21 | def unique_index_of( word )
22 | @unique.index(word)
23 | end
24 |
25 | def add_unique_word( word )
26 | @unique << word
27 | unique.size - 1
28 | end
29 | end
30 |
--------------------------------------------------------------------------------
/10/compressor4_spec.rb:
--------------------------------------------------------------------------------
1 | require 'ex_compressor4'
2 | require 'compressor_examples'
3 |
--------------------------------------------------------------------------------
/10/ex_compressor3_spec.rb:
--------------------------------------------------------------------------------
1 | require 'compressor3'
2 | require 'compressor_examples'
3 |
4 | describe TextCompressor do ##(main
5 |
6 | it "should be able to add some text" do
7 | c = TextCompressor.new( '' )
8 | c.add_text( 'first second' )
9 | c.unique.should == [ 'first', 'second' ]
10 | c.index.should == [ 0, 1 ]
11 | end
12 |
13 | it "should be able to add a word" do
14 | c = TextCompressor.new( '' )
15 | c.add_word( 'first' )
16 | c.unique.should == [ 'first' ]
17 | c.index.should == [ 0 ]
18 | end
19 |
20 | it "should be able to find the index of a word" do
21 | c = TextCompressor.new( 'hello world' )
22 | c.unique_index_of( 'hello' ).should == 0
23 | c.unique_index_of( 'world' ).should == 1
24 | end
25 |
26 | # ...
27 | end ##main)
28 |
--------------------------------------------------------------------------------
/10/ex_compressor4.rb:
--------------------------------------------------------------------------------
1 | class TextCompressor
2 | attr_reader :unique, :index
3 |
4 | def initialize( text )
5 | @unique = []
6 | @index = []
7 | add_text( text )
8 | end
9 |
10 | def add_text( text )
11 | words = text.split
12 | words.each { |word| add_word( word ) }
13 | end
14 |
15 | def add_word( word )
16 | i = unique_index_of( word ) || add_unique_word( word )
17 | @index << i
18 | end
19 |
20 | def unique_index_of( word )
21 | @unique.index(word)
22 | end
23 | end
24 |
25 | class TextCompressor ##(main
26 | # ...
27 |
28 | def add_unique_word( word )
29 | add_word_to_unique_array( word )
30 | last_index_of_unique_array
31 | end
32 |
33 | def add_word_to_unique_array( word )
34 | @unique << word
35 | end
36 |
37 | def last_index_of_unique_array
38 | unique.size - 1
39 | end
40 | end ##main)
41 |
--------------------------------------------------------------------------------
/10/pretentious_examples.rb:
--------------------------------------------------------------------------------
1 |
2 |
3 | describe 'Pretentions ratings' do
4 | it 'should return the right rating' do
5 | doc = Document.new( 1.0, 0.1 ).prose_rating.should == :really_pretentious
6 | doc = Document.new( 1.0, 0.199 ).prose_rating.should == :really_pretentious
7 | doc = Document.new( 1.0, 0.3 ).prose_rating.should == :somewhat_pretentious
8 | doc = Document.new( 1.0, 0.4 ).prose_rating.should == :somewhat_pretentious
9 |
10 | doc = Document.new( 0.2, 0.1 ).prose_rating.should == :about_right
11 | doc = Document.new( 0.2, 0.199 ).prose_rating.should == :about_right
12 | doc = Document.new( 0.19, 0.9 ).prose_rating.should == :about_right
13 |
14 | doc = Document.new( 0.0, 0.4 ).prose_rating.should == :really_informal
15 | doc = Document.new( 0.05, 0.29 ).prose_rating.should == :somewhat_informal
16 | end
17 |
18 | end
19 |
--------------------------------------------------------------------------------
/10/simple_memo.rb:
--------------------------------------------------------------------------------
1 |
2 |
3 | class
4 |
--------------------------------------------------------------------------------
/11/Rakefile:
--------------------------------------------------------------------------------
1 | require '../utils/tasks.rb'
2 |
3 | CLEAN.include(%w{notbest.txt total.txt type_error.txt unsure.txt})
4 |
5 |
--------------------------------------------------------------------------------
/11/doc_plus.rb:
--------------------------------------------------------------------------------
1 | class Document ##(class
2 | # Most of the class omitted...
3 |
4 | def +(other) ##(method
5 | Document.new( title, author, "#{content} #{other.content}" )
6 | end ##method)
7 | end ##class)
8 |
--------------------------------------------------------------------------------
/11/ex_1_adddoc_spec.rb:
--------------------------------------------------------------------------------
1 | require '../code/doc3'
2 | require '../utils/rspec_utils'
3 | require 'pp'
4 |
5 | require 'doc_plus.rb'
6 |
7 | describe Document do
8 | it "should be able to add" do
9 |
10 | out = output_of {
11 | doc1 = Document.new('Tag Line1', 'Kirk', "These are the voyages") ##(ex
12 | doc2 = Document.new('Tag Line2', 'Kirk', "of the star ship ...")
13 |
14 | total_document = doc1 + doc2
15 | puts total_document.content ##ex)
16 | }
17 | out.should match(/These.*star ship*/)
18 | File.write( 'total.txt', out)
19 |
20 | end
21 | end
22 |
--------------------------------------------------------------------------------
/11/ex_1_operators_are_methods_spec.rb:
--------------------------------------------------------------------------------
1 |
2 | describe 'operators are methods' do
3 | it '+ should be a method call' do
4 | first = mock
5 | second = mock
6 | first.should_receive(:+).twice.with(second).and_return(:the_sum)
7 |
8 | sum = first + second ##+op1
9 | sum.should == :the_sum
10 |
11 | sum = first.+(second) ##+method1
12 | sum.should == :the_sum
13 | end
14 |
15 | it 'should do the methods in the right order' do
16 | fourth = mock
17 | third = mock
18 | second = mock
19 | first = mock
20 |
21 | third.should_receive(:-).twice.with(fourth).and_return(:aaa)
22 | second.should_receive(:*).twice.with(:aaa).and_return(:bbb)
23 | first.should_receive(:+).twice.with(:bbb).and_return(:ccc)
24 |
25 | result = first + second * (third - fourth) ##+op2
26 | result.should == :ccc
27 |
28 | result = first.+(second.*(third.-(fourth))) ##+method2
29 | result.should == :ccc
30 |
31 | end
32 | end
33 |
34 |
35 |
--------------------------------------------------------------------------------
/11/ex_2_array_shift_spec.rb:
--------------------------------------------------------------------------------
1 | describe Array do
2 | it 'should be able to shift new items in' do
3 | names = [] ##(main
4 | names << 'Rob' # names.size is now 1
5 | names << 'Denise' # names.size is now 2 ##main)
6 |
7 | names.should == %w{ Rob Denise }
8 | end
9 | end
10 |
11 |
--------------------------------------------------------------------------------
/11/known_words.txt:
--------------------------------------------------------------------------------
1 | foo
2 | and
3 | Float
4 | Vector
5 | Matrix
6 | Set
7 | Fixnum
8 | sprintf
9 |
--------------------------------------------------------------------------------
/12/Rakefile:
--------------------------------------------------------------------------------
1 | require '../utils/tasks.rb'
2 |
--------------------------------------------------------------------------------
/12/document_identifier.rb:
--------------------------------------------------------------------------------
1 | class DocumentIdentifier
2 | attr_reader :folder, :name
3 |
4 | def initialize( folder, name )
5 | @folder = folder
6 | @name = name
7 | end
8 | end
9 |
--------------------------------------------------------------------------------
/12/ex_11_disarray_spec.rb:
--------------------------------------------------------------------------------
1 | require 'pp'
2 |
3 | class DisArray ##(main
4 |
5 | attr_reader :my_array
6 |
7 | def initialize
8 | @my_array = []
9 | end
10 |
11 | def ==(other)
12 | return false unless other.kind_of?(DisArray)
13 | @my_array == other.my_array
14 | end
15 |
16 | def eql?(other)
17 | return false unless other.kind_of?(DisArray)
18 | @my_array.eql?( other.my_array )
19 | end
20 |
21 | def hash
22 | @my_array.hash
23 | end
24 |
25 | # Rest of the class omitted...
26 | end ##main)
27 |
28 |
29 | describe DisArray do
30 | before :each do
31 | @da = DisArray.new
32 | end
33 |
34 | it 'should have a good == method' do
35 | @da.should == @da
36 | (@da == DisArray.new).should == true
37 | end
38 |
39 | it 'should work in a hash' do
40 | hash = {}
41 | hash[@da] = 1
42 | hash[@da].should == 1
43 | hash[DisArray.new].should == 1
44 | hash[:whatever].should == nil
45 | end
46 | end
47 |
--------------------------------------------------------------------------------
/12/ex_1_equal_spec.rb:
--------------------------------------------------------------------------------
1 |
2 | require 'document_identifier'
3 |
4 | describe DocumentIdentifier do
5 |
6 | it "should repect equal?" do
7 | i1 = DocumentIdentifier.new( 'books', 'warandpeace' )
8 | i2 = i1
9 | i3 = DocumentIdentifier.new( 'books', 'warandpeace' )
10 | i1.equal?(i1).should == true
11 | i1.equal?(i2).should == true
12 | i1.equal?(i3).should == false
13 | end
14 |
15 | it "should have the default ==" do
16 | first_id = DocumentIdentifier.new( 'secret/plans', 'raygun.txt' ) ##(intro
17 | second_id = DocumentIdentifier.new('secret/plans', 'raygun.txt' )
18 |
19 | puts "They are equal!" if first_id == second_id ##intro)
20 |
21 | (first_id == second_id).should == false
22 | end
23 |
24 | end
25 |
--------------------------------------------------------------------------------
/12/ex_3_fast_double_equals_spec.rb:
--------------------------------------------------------------------------------
1 | require 'document_identifier'
2 | require '../utils/rspec_utils'
3 |
4 | class DocumentIdentifier ##(doc_id
5 |
6 | # ...
7 |
8 | def ==(other)
9 | return true if other.equal?(self)
10 | return false unless other.instance_of?(self.class)
11 | folder == other.folder && name == other.name
12 | end
13 | end ##doc_id)
14 |
15 |
16 |
17 | describe DocumentIdentifier do
18 |
19 | it "should have the a good ==" do
20 | first_id = DocumentIdentifier.new( 'secret/plans', 'raygun.txt' )
21 | second_id = DocumentIdentifier.new('secret/plans', 'raygun.txt' )
22 |
23 | (first_id == first_id).should == true
24 | (first_id == second_id).should == true
25 | (first_id == 444).should == false
26 |
27 | output_of {
28 | puts "They are equal!" if first_id == second_id ##+demo
29 | }.should == "They are equal!\n"
30 | end
31 |
32 | end
33 |
--------------------------------------------------------------------------------
/12/ex_6_responds_to_spec.rb:
--------------------------------------------------------------------------------
1 |
2 | require 'document_identifier'
3 |
4 | class DocumentIdentifier
5 |
6 | # ...
7 |
8 | def ==(other)
9 | return false unless other.respond_to?(:folder)
10 | return false unless other.respond_to?(:name)
11 | folder == other.folder && name == other.name
12 | end
13 | end
14 |
15 |
16 |
17 | class DocumentPointer
18 | attr_reader :folder, :name
19 |
20 | def initialize( folder, name )
21 | @folder = folder
22 | @name = name
23 | end
24 | end
25 |
26 | describe DocumentIdentifier do
27 |
28 | it 'should be equal to a doc pointer' do
29 | identifier = DocumentIdentifier.new( 'secret/map', 'area51.gif' )
30 | pointer = DocumentPointer .new('secret/map', 'area51.gif' )
31 |
32 | (identifier == pointer).should == true
33 | (pointer == identifier).should == false
34 | end
35 | end
36 |
37 |
--------------------------------------------------------------------------------
/12/ex_8_regexp_spec.rb:
--------------------------------------------------------------------------------
1 |
2 |
3 | describe Regexp do
4 |
5 | it 'should support =~ as matching and == as equality' do
6 | (
7 | /Roswell.*/ =~ 'Roswell' # Yes! ##+main
8 | ).should_not == nil
9 |
10 | (
11 | /Roswell.*/ == 'Roswell' # No! ##+main
12 | ).should == false # No!
13 | end
14 |
15 | it 'should work in a case statement' do
16 | result = ''
17 | location = 'area 51' ##(case
18 |
19 | case location
20 | when /area.*/
21 | # ...
22 | result = 'A51' ##--case
23 | when /roswell.*/
24 | # ...
25 | else
26 | # ...
27 | end ##case)
28 |
29 | result.should == 'A51'
30 | end
31 |
32 | end
33 |
34 |
--------------------------------------------------------------------------------
/12/ex_9_bad_key_spec.rb:
--------------------------------------------------------------------------------
1 | require '../code/doc3'
2 | require 'document_identifier'
3 |
4 | class DocumentIdentifier
5 |
6 | # ...
7 |
8 | def ==(other)
9 | return false unless other.respond_to?(:folder)
10 | return false unless other.respond_to?(:name)
11 | folder == other.folder && name == other.name
12 | end
13 | end
14 |
15 |
16 | describe DocumentIdentifier do
17 | it 'should fail as a hash key' do
18 | hash = {} ##(simple
19 | document = Document.new( 'cia', 'Roswell', 'story' )
20 | first_id = DocumentIdentifier.new( 'public', 'CoverStory' )
21 |
22 | hash[first_id] = document ##simple)
23 |
24 |
25 | hash[first_id].equal?(document).should == true
26 |
27 | second_id = DocumentIdentifier.new( 'docs/public', 'CoverStory' ) ##(id2
28 | the_doc_again = hash[second_id] ##id2)
29 |
30 | the_doc_again.should == nil
31 | end
32 | end
33 |
34 |
--------------------------------------------------------------------------------
/12/known_words.txt:
--------------------------------------------------------------------------------
1 | object_id
2 | >=
3 |
--------------------------------------------------------------------------------
/13/Rakefile:
--------------------------------------------------------------------------------
1 | require '../utils/tasks.rb'
2 |
--------------------------------------------------------------------------------
/13/ex_3_uri_spec.rb:
--------------------------------------------------------------------------------
1 | require 'pp'
2 |
3 | describe 'uri class methods' do
4 |
5 | it 'should work like the books says' do
6 | require 'uri' ##(inst
7 |
8 | google = URI.parse( 'http://www.google.com' )
9 |
10 | puts google.scheme # prints 'http'
11 | puts google.host # prints 'www.google.com' ##inst)
12 |
13 | pp URI.scheme_list ##+class
14 | end
15 | end
16 |
17 |
18 |
--------------------------------------------------------------------------------
/13/ex_4_date_spec.rb:
--------------------------------------------------------------------------------
1 | require 'date'
2 |
3 | describe Date do
4 | it 'should have a civil method' do
5 | require 'date' ##(civil
6 | xmas = Date.civil( 2010, 12, 25 ) ##civil)
7 | p xmas.to_s
8 | end
9 |
10 | it 'should have an ordinal method' do
11 | xmas = Date.ordinal( 2010, 359 ) ##+ord
12 | p xmas.to_s
13 | end
14 |
15 | it 'should have a commercial method' do
16 | xmas = Date.commercial( 2010, 51, 6 ) ##+com
17 | p xmas.to_s
18 | end
19 | end
20 |
--------------------------------------------------------------------------------
/13/ex_examples2_spec.rb:
--------------------------------------------------------------------------------
1 | class Document ##(main
2 | class << self
3 | def find_by_name( name )
4 | # Find a document by name...
5 | end
6 |
7 | def find_by_id( doc_id )
8 | # Find a document by id
9 | end
10 | end
11 | end ##main)
12 |
13 | describe Document do
14 | it "should have the singleton methods" do
15 | Document.find_by_name( 'doc' )
16 | Document.find_by_id( '124' )
17 | end
18 | end
19 |
--------------------------------------------------------------------------------
/13/ex_examples3_spec.rb:
--------------------------------------------------------------------------------
1 | require 'pp'
2 |
3 | describe "Singleton methods in stubs" do ##(main
4 | it "is just a demonstration of stubs as singleton methods" do
5 | stub_printer = stub :available? => true, :render => nil
6 | pp stub_printer.singleton_methods
7 | stub_printer.singleton_methods.should include(:available?) ##--main
8 | stub_printer.singleton_methods.should include(:render) ##--main
9 | end
10 | end ##main)
11 |
--------------------------------------------------------------------------------
/13/ex_examples4_spec.rb:
--------------------------------------------------------------------------------
1 | require '../code/doc3'
2 |
3 | class Document ##(doc
4 | def self.create_test_document( length )
5 | Document.new( 'test', 'test', 'test ' * length )
6 | end
7 |
8 | # ...
9 | end ##doc)
10 |
11 | describe Document do
12 | it 'should have a create_test_document method' do
13 | book = Document.create_test_document( 10000 ) ##+good
14 |
15 | lambda {
16 | longer_doc = book.create_test_document( 20000 ) ##+bad
17 | }.should raise_error(NoMethodError)
18 |
19 | longer_doc = book.class.create_test_document( 20000 ) ##+fixed
20 | end
21 | end
22 |
--------------------------------------------------------------------------------
/13/ex_examples5_spec.rb:
--------------------------------------------------------------------------------
1 | require '../utils/rspec_utils'
2 |
3 | class Parent ##(main
4 | def self.who_am_i
5 | puts "The value of self is #{self}"
6 | end
7 | end
8 |
9 | class Child < Parent
10 | end ##main)
11 |
12 | describe Child do
13 | it 'should output the child class name' do
14 | out = output_of { Parent.who_am_i }
15 | out.should match(/Parent/)
16 | out = output_of { Child.who_am_i }
17 | out.should match(/Child/)
18 | end
19 | end
20 |
--------------------------------------------------------------------------------
/13/mocha_demo.rb:
--------------------------------------------------------------------------------
1 | require 'mocha'
2 |
3 | include Mocha::API
4 |
5 | class Document
6 | end
7 |
8 | mock_doc = Document.new
9 | mock_doc.expects(:words).returns( %w{Call me Ishmael} )
10 | mock_doc.expects(:word_count).returns( 3 )
11 | p mock_doc.singleton_methods
12 |
--------------------------------------------------------------------------------
/13/t1.rb:
--------------------------------------------------------------------------------
1 | require 'test/unit'
2 | require 'mocha'
3 |
4 | class Product
5 | def self.find(n)
6 | end
7 | end
8 |
9 | class MiscExampleTest < Test::Unit::TestCase
10 |
11 | def test_mocking_a_class_method
12 | product = Product.new
13 | Product.expects(:find).with(1).returns(product)
14 | #assert_equal product, Product.find(1)
15 | end
16 | end
17 |
--------------------------------------------------------------------------------
/13/telling.txt:
--------------------------------------------------------------------------------
1 | I'm not telling
2 |
--------------------------------------------------------------------------------
/14/Rakefile:
--------------------------------------------------------------------------------
1 | require '../utils/tasks.rb'
2 |
--------------------------------------------------------------------------------
/14/document_with_accessor_iv.rb:
--------------------------------------------------------------------------------
1 | require '../code/doc3'
2 |
3 | class Document ##(main
4 |
5 | @default_font = :times
6 |
7 | class << self
8 | attr_accessor :default_font
9 | end
10 |
11 | # Rest of the class omitted...
12 | end ##main)
13 |
14 | class Document
15 |
16 | attr_accessor :font
17 |
18 | def initialize(title, author)
19 | @title = title
20 | @author = author
21 | @font = Document.default_font
22 | end
23 |
24 | end
25 |
--------------------------------------------------------------------------------
/14/document_with_cv.rb:
--------------------------------------------------------------------------------
1 | require '../code/doc3'
2 |
3 | class Document ##(main
4 |
5 | @@default_paper_size = :a4
6 |
7 | def self.default_paper_size
8 | @@default_paper_size
9 | end
10 |
11 | def self.default_paper_size=(new_size)
12 | @@default_paper_size = new_size
13 | end
14 |
15 | attr_accessor :title, :author, :content
16 | attr_accessor :paper_size
17 |
18 | def initialize(title, author, content)
19 | @title = title
20 | @author = author
21 | @content = content
22 | @paper_size = @@default_paper_size
23 | end
24 |
25 | # Rest of the class omitted...
26 | end ##main)
27 |
--------------------------------------------------------------------------------
/14/document_with_default_font.rb:
--------------------------------------------------------------------------------
1 | require 'document_with_cv'
2 |
3 |
4 | class Document ##(main
5 | @@default_font = :times
6 |
7 | # Rest of the class omitted...
8 | end ##main)
9 |
10 | class Document
11 | def self.default_font=(font)
12 | @@default_font = font
13 | end
14 |
15 |
16 | def self.default_font
17 | @@default_font
18 | end
19 | end
20 |
21 |
--------------------------------------------------------------------------------
/14/document_with_iv.rb:
--------------------------------------------------------------------------------
1 | require '../code/doc3'
2 |
3 | class Document ##(iv
4 |
5 | @default_font = :times
6 |
7 | def self.default_font=(font)
8 | @default_font = font
9 | end
10 |
11 | def self.default_font
12 | @default_font
13 | end
14 |
15 | # Rest of the class omitted...
16 | end ##iv)
17 |
18 | class Document
19 |
20 | attr_accessor :font
21 |
22 | def initialize(title, author) ##(init
23 | @title = title
24 | @author = author
25 | @font = Document.default_font
26 | end ##init)
27 |
28 | end
29 |
--------------------------------------------------------------------------------
/14/document_with_iv_examples.rb:
--------------------------------------------------------------------------------
1 | describe Document do
2 |
3 | it 'should start with a default paper size' do
4 | Document.default_font.should == :times
5 | Document.default_font = :dingbat
6 | Document.default_font.should == :dingbat
7 | end
8 |
9 | it 'should pass on the default font to the subclases' do
10 | d = Document.new( 'example', 'russ' )
11 | d.font.should == Document.default_font
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/14/document_with_silly_instance_variable_spec.rb:
--------------------------------------------------------------------------------
1 | class Document ##(main
2 | attr_accessor :default_font
3 | end ##main)
4 |
5 |
6 | describe Document do
7 | it 'should have a default font instance var' do
8 | doc = Document.new
9 | doc.default_font = 'foo'
10 | doc.default_font.should == 'foo'
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/14/ex_1_document_with_cv_spec.rb:
--------------------------------------------------------------------------------
1 |
2 | require 'document_with_cv'
3 |
4 | describe Document do
5 |
6 | it 'should start with a default paper size' do
7 | Document.default_paper_size.should == :a4
8 | Document.default_paper_size = :us_letter
9 | Document.default_paper_size.should == :us_letter
10 | end
11 |
12 | end
13 |
--------------------------------------------------------------------------------
/14/ex_3_doc_disaster_spec.rb:
--------------------------------------------------------------------------------
1 | require 'document_with_default_font'
2 | require 'presentation'
3 | require 'resume'
4 |
5 | require 'pp'
6 |
7 | describe 'Document and subclasses fighting' do
8 |
9 | it 'Document has the only class variable' do
10 | Document.class_variable_defined?(:@@default_font).should == true
11 | Document.default_font.should == :arial # from resume
12 | Resume.default_font.should == :arial
13 | Presentation.default_font.should == :arial
14 |
15 | Resume.default_font = :for_resume
16 | Document.default_font.should == :for_resume
17 | Resume.default_font.should == :for_resume
18 | Presentation.default_font.should == :for_resume
19 |
20 | Presentation.default_font = :for_pres
21 | Document.default_font.should == :for_pres
22 | Resume.default_font.should == :for_pres
23 | Presentation.default_font.should == :for_pres
24 | end
25 | end
26 |
--------------------------------------------------------------------------------
/14/ex_4_more_doc_disaster_spec.rb:
--------------------------------------------------------------------------------
1 | require 'document_with_default_font'
2 | require 'resume'
3 | require 'presentation'
4 |
5 |
6 |
7 | describe 'Loading presentation last changes global def font' do
8 |
9 | it 'Document has the only class variable' do
10 | Document.class_variable_defined?(:@@default_font).should == true
11 | Document.default_font.should == :nimbus
12 | Resume.default_font.should == :nimbus
13 | Presentation.default_font.should == :nimbus
14 | end
15 | end
16 |
--------------------------------------------------------------------------------
/14/ex_5_document_with_iv_spec.rb:
--------------------------------------------------------------------------------
1 |
2 | require 'document_with_iv'
3 |
4 | require 'document_with_iv_examples'
5 |
--------------------------------------------------------------------------------
/14/ex_6_document_with_accessor_spec.rb:
--------------------------------------------------------------------------------
1 |
2 | require 'document_with_accessor_iv'
3 |
4 | require 'document_with_iv_examples'
5 |
--------------------------------------------------------------------------------
/14/ex_8_wild.rb:
--------------------------------------------------------------------------------
1 | require 'uri'
2 |
3 | describe URI do
4 |
5 | it 'should work like the book says' do
6 | my_uri = URI.parse('http://www.russolsen.com') ##+uri
7 | my_uri.host.should == 'www.russolsen.com'
8 | my_uri.scheme.should == 'http'
9 | my_url.port.should == 80
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/14/presentation.rb:
--------------------------------------------------------------------------------
1 | class Presentation < Document
2 | @@default_font = :nimbus
3 |
4 | def self.default_font=(font)
5 | @@default_font = font
6 | end
7 |
8 |
9 | def self.default_font
10 | @@default_font
11 | end
12 |
13 | attr_accessor :font
14 |
15 | def initialize
16 | @font = @@default_font
17 | end
18 |
19 | # Rest of the class omitted...
20 | end
21 |
22 |
--------------------------------------------------------------------------------
/14/resume.rb:
--------------------------------------------------------------------------------
1 | class Resume < Document
2 | @@default_font = :arial
3 |
4 | def self.default_font=(font)
5 | @@default_font = font
6 | end
7 |
8 |
9 | def self.default_font
10 | @@default_font
11 | end
12 |
13 | attr_accessor :font
14 |
15 |
16 | def initialize
17 | @font = @@default_font
18 | end
19 |
20 | # Rest of the class omitted...
21 | end
22 |
--------------------------------------------------------------------------------
/14/resume_presentation_with_iv.rb:
--------------------------------------------------------------------------------
1 | require 'document_with_accessor_iv'
2 |
3 | class Presentation < Document ##(pres
4 |
5 | @default_font = :nimbus
6 |
7 | class << self
8 | attr_accessor :default_font
9 | end
10 |
11 | def initialize(title, author)
12 | @title = title
13 | @author = author
14 | @font = Presentation.default_font
15 | end
16 |
17 | # most of the class omitted...
18 | end ##pres)
19 |
20 | class Resume < Document ##(resume
21 |
22 | @default_font = :arial
23 |
24 | class << self
25 | attr_accessor :default_font
26 | end
27 |
28 | def initialize(title, author)
29 | @title = title
30 | @author = author
31 | @font = Presentation.default_font
32 | end
33 |
34 | # most of the class omitted...
35 | end ##resume)
36 |
37 |
--------------------------------------------------------------------------------
/15/Rakefile:
--------------------------------------------------------------------------------
1 | require '../utils/tasks.rb'
2 |
--------------------------------------------------------------------------------
/15/demo_bit_at_a_time.rb:
--------------------------------------------------------------------------------
1 | ##
2 |
3 | module Rendering
4 | class Font
5 | def initialize( name, weight=:normal, size=10 )
6 | end
7 | end
8 |
9 | class PaperSize
10 | def initialize( name='US Let', width=8.5, height=11.0 )
11 | end
12 | end
13 | end
14 |
15 |
16 | module Rendering ##(bit_font
17 | class Font
18 | # Bulk of class omitted...
19 | end
20 |
21 | DEFAULT_FONT = Font.new( 'default' )
22 | end ##bit_font)
23 |
24 | module Rendering ##(bit_paper
25 | class PaperSize
26 | # Bulk of class omitted...
27 | end
28 |
29 | DEFAULT_PAPER_SIZE = PaperSize.new
30 | end ##bit_paper)
31 |
32 | raise "failed" unless Rendering::Font.instance_of?(Class)
33 | raise "failed" unless Rendering::DEFAULT_FONT.instance_of?(Rendering::Font)
34 |
35 | raise "failed" unless Rendering::PaperSize.instance_of?(Class)
36 | raise "failed" unless Rendering::DEFAULT_PAPER_SIZE.instance_of?(Rendering::PaperSize)
37 |
38 |
--------------------------------------------------------------------------------
/15/ex_print_papersize_demo.rb:
--------------------------------------------------------------------------------
1 | require 'ex_rendering'
2 |
3 | include Rendering ##(main
4 |
5 | puts "The default paper height is #{DEFAULT_PAPER_SIZE.height}" ##main)
6 |
7 |
--------------------------------------------------------------------------------
/15/ex_rendering.rb:
--------------------------------------------------------------------------------
1 | ##
2 |
3 | module Rendering ##(basic
4 | class Font
5 | attr_accessor :name, :weight, :size
6 |
7 | def initialize( name, weight=:normal, size=10 )
8 | @name = name
9 | @weight = weight
10 | @size = size
11 | end
12 |
13 | # Rest of the class omitted...
14 | end
15 |
16 | class PaperSize
17 | attr_accessor :name, :width, :height
18 |
19 | def initialize( name='US Let', width=8.5, height=11.0 )
20 | @name = name
21 | @width = width
22 | @height = height
23 | end
24 | # Rest of the class omitted...
25 | end
26 | end ##basic)
27 |
28 | module Rendering ##(const
29 | # Font and PaperSize classes omitted...
30 |
31 | DEFAULT_FONT = Font.new( 'default' )
32 | DEFAULT_PAPER_SIZE = PaperSize.new
33 | end ##const)
34 |
35 |
--------------------------------------------------------------------------------
/15/ex_wp_points_spec.rb:
--------------------------------------------------------------------------------
1 |
2 | require 'wp_points'
3 |
4 | describe WordProcessor do
5 |
6 | it "should have points conversion methods" do
7 | WordProcessor.points_to_inches( 72.0 ).should == 1.0
8 | WordProcessor.points_to_inches( 720.0 ).should == 10.0
9 | an_inch_full_of_points = WordProcessor.inches_to_points( 1.0 ) ##+main
10 | an_inch_full_of_points.should == 72.0
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/15/known_words.txt:
--------------------------------------------------------------------------------
1 | Date
2 | DataMapper
3 |
--------------------------------------------------------------------------------
/15/mod_printer_classes.rb:
--------------------------------------------------------------------------------
1 | module TonsOToner ##(tot
2 | class PrintQueue
3 | def submit( print_job )
4 | # Send the job off for printing to this laser printer
5 | end
6 |
7 | def cancel( print_job)
8 | # Stop!
9 | end
10 | end
11 |
12 | class Administration
13 | def power_off
14 | # Turn this laser printer off...
15 | end
16 |
17 | def start_self_test
18 | # Everything ok?
19 | end
20 | end
21 | end ##tot)
22 |
23 |
24 | module OceansOfInk ##(ooi
25 | class PrintQueue
26 | def submit( print_job )
27 | # Send the job off for printing to this ink jet printer
28 | end
29 | # Rest omitted...
30 | end
31 |
32 | class Administration
33 | # Ink jet administration code omitted...
34 | end
35 | end ##ooi)
36 |
--------------------------------------------------------------------------------
/15/printer_classes.rb:
--------------------------------------------------------------------------------
1 | class TonsOTonerPrintQueue
2 | def submit( print_job )
3 | # Send the job off for printing to this laser printer...
4 | end
5 |
6 | def cancel( print_job)
7 | # Stop the print job on this laser printer...
8 | end
9 | end
10 |
11 | class TonsOTonerAdministration
12 | def power_off
13 | # Turn this laser printer off...
14 | end
15 |
16 | def start_self_test
17 | # Test this laser printer...
18 | end
19 | end
20 |
21 | class OceansOfInkPrintQueue
22 | def submit( print_job )
23 | # Send the job off for printing to this ink jet printer...
24 | end
25 |
26 | def cancel( print_job)
27 | # Stop the print job on this ink jet printer...
28 | end
29 | end
30 |
31 | Class OceansOfInkAdministration
32 | def power_off
33 | # Turn this ink jet printer off...
34 | end
35 |
36 | def start_self_test
37 | # Test this ink jet printer...
38 | end
39 | end
40 |
--------------------------------------------------------------------------------
/15/trouble_mod_bad.rb:
--------------------------------------------------------------------------------
1 | module WordProcessor
2 |
3 | def points_to_inches( points )
4 | points / 72.0
5 | end
6 |
7 | # etc...
8 | end
9 |
10 |
--------------------------------------------------------------------------------
/15/trouble_mod_bad_spec.rb:
--------------------------------------------------------------------------------
1 |
2 | require 'trouble_mod_bad'
3 | include WordProcessor
4 |
5 | describe WordProcessor do
6 |
7 | it "should have instance points conversion methods" do
8 | points_to_inches( 72.0 ).should == 1.0
9 | end
10 | end
11 |
--------------------------------------------------------------------------------
/15/trouble_mod_good.rb:
--------------------------------------------------------------------------------
1 | module WordProcessor
2 |
3 | def self.points_to_inches( points )
4 | points / 72.0
5 | end
6 |
7 | # etc...
8 | end
9 |
--------------------------------------------------------------------------------
/15/trouble_mod_good_spec.rb:
--------------------------------------------------------------------------------
1 |
2 | require 'trouble_mod_good'
3 |
4 | describe WordProcessor do
5 |
6 | it "should have points conversion methods" do
7 | WordProcessor.points_to_inches( 72.0 ).should == 1.0
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/15/word_processor.rb:
--------------------------------------------------------------------------------
1 | module WordProcessor
2 | module Rendering
3 | class Font
4 | # Guts of class omitted...
5 | end
6 |
7 | # and so on...
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/15/word_processor_spec.rb:
--------------------------------------------------------------------------------
1 | require 'word_processor'
2 |
3 | describe WordProcessor do
4 |
5 | it "should have a Font class" do
6 | WordProcessor.should be_an_instance_of( Module )
7 | WordProcessor::Rendering.should be_an_instance_of( Module )
8 | WordProcessor::Rendering::Font.should be_an_instance_of( Class )
9 | end
10 |
11 | end
12 |
--------------------------------------------------------------------------------
/15/wp_points.rb:
--------------------------------------------------------------------------------
1 | module WordProcessor
2 |
3 | def self.points_to_inches( points )
4 | points / 72.0
5 | end
6 |
7 | def self.inches_to_points( inches )
8 | inches * 72.0
9 | end
10 |
11 | # Rest of the module omitted
12 | end
13 |
--------------------------------------------------------------------------------
/16/Rakefile:
--------------------------------------------------------------------------------
1 | require '../utils/tasks.rb'
2 |
--------------------------------------------------------------------------------
/16/electronic_text.rb:
--------------------------------------------------------------------------------
1 | class ElectronicText ##(text
2 | attr_accessor :title, :author, :content
3 |
4 | def initialize( title, author, content )
5 | @title = title
6 | @author = author
7 | @content = content
8 | end
9 | end ##text)
10 |
11 | class ElectronicBook < ElectronicText ##(book
12 | # Lots of complicated stuff omitted...
13 | end ##book)
14 |
--------------------------------------------------------------------------------
/16/ex_1_doc_with_method_spec.rb:
--------------------------------------------------------------------------------
1 | require '../code/doc3'
2 |
3 | class Document ##(main
4 |
5 | CLICHES = [ /play fast and loose/,
6 | /make no mistake/,
7 | /does the trick/,
8 | /off and running/,
9 | /my way or the highway/ ]
10 |
11 | def number_of_cliches
12 | CLICHES.inject(0) do |count, phrase|
13 | count += 1 if phrase =~ content
14 | count
15 | end
16 | end
17 |
18 | # Rest of the class omitted...
19 | end ##main)
20 |
21 | require 'prose_quality_examples'
22 |
--------------------------------------------------------------------------------
/16/ex_3_prose_quality_mixin_spec.rb:
--------------------------------------------------------------------------------
1 | require '../code/doc3'
2 | require 'electronic_text'
3 | require 'writing_quality_mixin'
4 |
5 | class Document ##(wq_mixin_classes
6 | include WritingQuality
7 |
8 | # Lots of stuff omitted...
9 | end
10 |
11 | class ElectronicBook < ElectronicText
12 | include WritingQuality
13 |
14 | # Lots of stuff omitted...
15 | end ##wq_mixin_classes)
16 |
17 | require 'prose_quality_examples'
18 |
19 | describe 'Document and ebook' do
20 | it 'should have working examples' do
21 | text = "my way or the highway does the trick" ##(doc_demo
22 | my_tome = Document.new('Hackneyed', 'Russ', text)
23 | puts my_tome.number_of_cliches ##doc_demo)
24 |
25 | my_ebook = ElectronicBook.new( 'EHackneyed', 'Russ', text) ##(ebook_demo
26 | puts my_ebook.number_of_cliches ##ebook_demo)
27 |
28 | my_tome.number_of_cliches.should == 2
29 | my_ebook.number_of_cliches.should == 2
30 | end
31 | end
32 |
33 |
34 |
--------------------------------------------------------------------------------
/16/ex_4_multiple_modules_spec.rb:
--------------------------------------------------------------------------------
1 | require '../code/doc3'
2 | require 'electronic_text'
3 | require 'writing_quality_mixin'
4 |
5 | module ProjectManagement
6 | def proj_man
7 | end
8 | end
9 |
10 | module AuthorAccountTracking
11 | def author_account
12 | end
13 | end
14 |
15 | module ProjectManagement ##(more_mods
16 | # Lots of boring stuff omitted
17 | end
18 |
19 | module AuthorAccountTracking
20 | # Lots of even more boring stuff omitted
21 | end
22 |
23 | class ElectronicBook < ElectronicText
24 | include WritingQuality
25 | include ProjectManagement
26 | include AuthorAccountTracking
27 |
28 | # Lots of stuff omitted...
29 | end ##more_mods)
30 |
31 | describe ElectronicBook do
32 | it 'should have all the methods from all the modules' do
33 | eb = ElectronicBook.new( 'test', 'russ', 'hello' )
34 | eb.number_of_cliches.should == 0
35 | lambda { eb.proj_man }.should_not raise_error
36 | lambda { eb.author_account }.should_not raise_error
37 | end
38 | end
39 |
40 |
--------------------------------------------------------------------------------
/16/ex_5_class_mixin_spec.rb:
--------------------------------------------------------------------------------
1 | require '../code/doc3'
2 |
3 | module Finders ##(finders
4 | def find_by_name( name )
5 | # Find a document by name...
6 | end
7 |
8 | def find_by_id( doc_id )
9 | # Find a document by id
10 | end
11 | end ##finders)
12 |
13 |
14 | class Document ##(inc_doc
15 | # Most of the class omitted...
16 |
17 | class << self
18 | include Finders
19 | end
20 | end ##inc_doc)
21 |
22 | describe 'document with finders' do
23 | it 'should have the right methods' do
24 | war_and_peace = Document.find_by_name( 'War And Peace' ) ##+war_and_peace
25 | war_and_peace = Document.find_by_name( '0123456' )
26 | end
27 | end
28 |
29 |
--------------------------------------------------------------------------------
/16/ex_6_class_extend_spec.rb:
--------------------------------------------------------------------------------
1 | require '../code/doc3'
2 |
3 | module Finders
4 | def find_by_name( name )
5 | # Find a document by name...
6 | end
7 |
8 | def find_by_id( doc_id )
9 | # Find a document by id
10 | end
11 | end
12 |
13 |
14 | class Document ##(extend
15 | extend Finders
16 |
17 | # Most of the class omitted...
18 | end ##extend)
19 |
20 |
21 | describe 'document with finders' do
22 | it 'should have the right methods' do
23 | war_and_peace = Document.find_by_name( 'War And Peace' )
24 | war_and_peace = Document.find_by_name( '0123456' )
25 | end
26 | end
27 |
28 |
--------------------------------------------------------------------------------
/16/ex_7_override_with_local_method_spec.rb:
--------------------------------------------------------------------------------
1 | require '../code/doc3'
2 |
3 | require 'writing_quality_mixin'
4 |
5 |
6 | class Document ##(override
7 | include WritingQuality
8 |
9 | # Rest of the class omitted...
10 | end
11 |
12 | class PoliticalBook < Document
13 | def number_of_cliches
14 | 0
15 | end
16 |
17 | # Rest of the class omitted...
18 | end ##override)
19 |
20 | describe PoliticalBook do
21 | it 'should always report zero cliches' do
22 | text = "my way or the highway does the trick"
23 | pb = PoliticalBook.new( 'speech', 'russ', text)
24 | pb.number_of_cliches.should == 0
25 | doc = Document.new( 'speech', 'russ', text)
26 | doc.number_of_cliches.should == 2
27 | end
28 | end
29 |
--------------------------------------------------------------------------------
/16/ex_8_override_with_another_module_spec.rb:
--------------------------------------------------------------------------------
1 | require '../code/doc3'
2 | require 'writing_quality_mixin'
3 |
4 |
5 | module PoliticalWritingQuality ##(pwq
6 | # No phrase is too worn out to be a cliché
7 | # in political writing
8 | def number_of_cliches
9 | 0
10 | end
11 | end ##pwq)
12 |
13 | class Document
14 | include WritingQuality
15 |
16 | # Rest of the class omitted...
17 | end
18 |
19 | class PoliticalBook < Document ##(pb
20 | include WritingQuality
21 | include PoliticalWritingQuality
22 |
23 | # Lots of stuff omitted...
24 | end ##pb)
25 |
26 | describe PoliticalBook do
27 | it 'should always report zero cliches' do
28 | text = "my way or the highway does the trick"
29 | pb = PoliticalBook.new( 'speech', 'russ', text)
30 | pb.number_of_cliches.should == 0
31 | doc = Document.new( 'speech', 'russ', text)
32 | doc.number_of_cliches.should == 2
33 | end
34 | end
35 |
--------------------------------------------------------------------------------
/16/prose_quality_examples.rb:
--------------------------------------------------------------------------------
1 | describe Document do
2 |
3 | it 'should report 0 cliches for a doc w/o cliches' do
4 | d = Document.new( 'no cliche', 'russ', 'This is original' )
5 | d.number_of_cliches.should == 0
6 | end
7 |
8 | it 'should report 0 cliches for a empty doc' do
9 | d = Document.new( 'no cliche', 'russ', '' )
10 | d.number_of_cliches.should == 0
11 | end
12 |
13 | it 'should report 1 cliches for a doc with 1 cliches' do
14 | d = Document.new( 'no cliche', 'russ', 'We need to make no mistake' )
15 | d.number_of_cliches.should == 1
16 | end
17 |
18 | it 'should report 3 cliches for a doc with 3 cliches' do
19 | content = 'does the trick my way or the highway off and running'
20 | d = Document.new( 'no cliche', 'russ', content )
21 | d.number_of_cliches.should == 3
22 | end
23 | end
24 |
--------------------------------------------------------------------------------
/16/writing_quality_mixin.rb:
--------------------------------------------------------------------------------
1 | module WritingQuality ##(main
2 |
3 | CLICHES = [ /play fast and loose/,
4 | /make no mistake/,
5 | /does the trick/,
6 | /off and running/,
7 | /my way or the highway/ ]
8 |
9 | def number_of_cliches ##(noc
10 | CLICHES.inject(0) do |count, phrase|
11 | count += 1 if phrase =~ content
12 | count
13 | end
14 | end ##noc)
15 | end ##main)
16 |
--------------------------------------------------------------------------------
/17/Rakefile:
--------------------------------------------------------------------------------
1 | require '../utils/tasks.rb'
2 |
3 | CLEAN.include(%w{choc.txt donuts.txt pi4.txt})
4 | CLEAN.include(%w{sorted_chars.txt with_arg.txt resolv.txt})
5 |
6 |
--------------------------------------------------------------------------------
/17/doc_each_word.rb:
--------------------------------------------------------------------------------
1 | class Document
2 |
3 | # Stuff omitted...
4 |
5 | def each_word ##(main
6 | words.each { |word| yield( word ) }
7 | end ##main)
8 | end
9 |
--------------------------------------------------------------------------------
/17/doc_with_each_char.rb:
--------------------------------------------------------------------------------
1 | class Document
2 | def each_character
3 | index = 0
4 | while index < @content.size
5 | yield( @content[index] )
6 | index += 1
7 | end
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/17/ex_2_basic_doc_iterator_spec.rb:
--------------------------------------------------------------------------------
1 |
2 | require '../code/doc3'
3 | require '../utils/rspec_utils'
4 |
5 | class Document ##(main
6 |
7 | # Stuff omitted...
8 |
9 | def each_word
10 | word_array = words
11 | index = 0
12 | while index < words.size
13 | yield( word_array[index] )
14 | index += 1
15 | end
16 | end
17 | end ##main)
18 |
19 | describe Document do
20 | it 'should have a good each_word method' do
21 | out = output_of {
22 | d = Document.new( 'Truth', 'Gump', 'Life is like a box of ...' ) ##(example
23 | d.each_word {|word| puts word} ##example)
24 | }
25 | out.should match( /Life\nis\nlike\n.*/m)
26 | File.write( 'choc.txt', out )
27 | end
28 | end
29 |
--------------------------------------------------------------------------------
/17/ex_3_easy_doc_iterator_spec.rb:
--------------------------------------------------------------------------------
1 |
2 | require '../code/doc3'
3 | require '../utils/rspec_utils'
4 | require 'doc_each_word'
5 |
6 | describe Document do
7 | it 'should have a good each_word method' do
8 | d = Document.new( 'Truth', 'Gump', 'Life is like a box of chocolates' )
9 | out = output_of {
10 | d.each_word {|word| puts word}
11 | }
12 | out.should match( /Life\nis\nlike\n.*choc.*/m)
13 | end
14 | end
15 |
--------------------------------------------------------------------------------
/17/ex_4_each_char_spec.rb:
--------------------------------------------------------------------------------
1 | require '../code/doc3'
2 | require '../utils/rspec_utils'
3 |
4 |
5 | class Document ##(main
6 |
7 | # Stuff omitted
8 |
9 | def each
10 | # iterate over the words as in our first example
11 | end
12 |
13 | def each_character
14 | # iterate over the characters
15 | end
16 | end ##main)
17 |
18 |
19 | require 'doc_with_each_char'
20 |
21 |
22 | describe Document do
23 | it 'should have a good each_character method' do
24 | d = Document.new( 'Truth', 'Gump', 'Life is like a box of chocolates' )
25 | out = output_of {
26 | d.each_character {|ch| puts ch}
27 | }
28 | out.should match( /L\ni\nf\n.*e\ns\n/m)
29 | end
30 | end
31 |
--------------------------------------------------------------------------------
/17/ex_5_each_word_pair_spec.rb:
--------------------------------------------------------------------------------
1 | require '../code/doc3'
2 | require '../utils/rspec_utils'
3 |
4 |
5 | class Document ##(pair
6 | # Most of the class omitted...
7 |
8 | def each_word_pair
9 | word_array = words
10 | index = 0
11 | while index < (word_array.size-1)
12 | yield word_array[index], word_array[index+1]
13 | index += 1
14 | end
15 | end
16 | end ##pair)
17 |
18 | describe Document do
19 | it 'should have a good each_word_pair method' do
20 | out = output_of {
21 | doc = Document.new('Donuts', '?', 'I love donuts mmmm donuts' ) ##(donuts
22 | doc.each_word_pair{ |first, second| puts "#{first} #{second}" } ##donuts)
23 | }
24 | out.should match( /I love\nlove donuts\ndonuts mmmm\nmmmm donuts\n/m )
25 | File.write( 'donuts.txt', out )
26 | end
27 | end
28 |
29 |
30 | describe "The times method" do
31 | it 'should work as advertised' do
32 | 12.times { |x| puts "The number is #{x}" } ##+times
33 | end
34 | end
35 |
--------------------------------------------------------------------------------
/17/ex_7_enumerator_spec.rb:
--------------------------------------------------------------------------------
1 | require '../code/doc3'
2 | require '../utils/rspec_utils'
3 | require 'doc_with_each_char'
4 | require 'pp'
5 |
6 | describe Document do
7 | it 'should work with enum' do
8 | doc = Document.new('example', 'russ', "We are all characters") ##(main
9 | enum = doc.enum_for(:each_character ) ##main)
10 |
11 | a = enum.to_a
12 | a[0].should == 'W'
13 | a[1].should == 'e'
14 | a.last.should == 's'
15 |
16 | sorted = enum.sort
17 | sorted[0].should == ' '
18 | sorted[3].should == 'W'
19 |
20 | output_of {
21 | puts enum.count ##+count
22 | }.should == "21\n"
23 |
24 | out = output_of {
25 | pp enum.sort ##+sort
26 | }
27 | File.write( 'sorted_chars.txt', out )
28 | end
29 | end
30 |
--------------------------------------------------------------------------------
/17/ex_8_trouble.rb:
--------------------------------------------------------------------------------
1 | require '../code/doc3'
2 | require '../utils/rspec_utils'
3 |
4 | class Document
5 | def each_word
6 | word_array = words
7 | index = 0
8 | while index < words.size
9 | yield( word_array[index] )
10 | index += 1
11 | end
12 | end
13 | end
14 |
15 | describe 'iterators and exceptions' do
16 | it 'should stop the iterator' do
17 | doc = Document.new('example', 'russ', "a b c now d")
18 |
19 | lambda {
20 | doc.each_word do |word| ##(boom
21 | raise 'boom' if word == 'now'
22 | end ##boom)
23 | }.should raise_error
24 |
25 | end
26 | end
27 |
--------------------------------------------------------------------------------
/17/ex_8c_break_spec.rb:
--------------------------------------------------------------------------------
1 | require '../code/doc3'
2 | require 'doc_each_word'
3 |
4 | def count_till_tuesday( doc ) ##(main
5 | count = 0
6 | doc.each_word do |word|
7 | count += 1
8 | break if word == 'Tuesday'
9 | end
10 | count ##main)
11 | end
12 |
13 |
14 | describe 'each_word method with break' do
15 |
16 | it 'should work exit the calling method' do
17 | doc = Document.new( 'whatever', 'russ', 'Monday Tuesday Wed' )
18 | count_till_tuesday( doc ).should == 2
19 | end
20 |
21 | end
22 |
--------------------------------------------------------------------------------
/17/ex_9_real_world_spec.rb:
--------------------------------------------------------------------------------
1 | require '../utils/rspec_utils'
2 | require 'resolv'
3 |
4 | describe Dir do
5 | it 'should run thru the files in a dir' do
6 | puts "Contents of /etc directory:" ##(dir
7 | etc_dir = Dir.new("/etc")
8 | etc_dir.each {|entry| puts entry} ##dir)
9 | end
10 | end
11 |
12 | describe Resolv do
13 | it 'should go thru the inet addresses' do
14 | out = output_of {
15 | Resolv.each_address( "www.google.com" ) {|a| puts a} ##+addr
16 | }
17 | File.write( 'resolv.txt', out )
18 | end
19 | end
20 |
21 | describe ObjectSpace do
22 | it 'should have an each_object method' do
23 | output_of {
24 | ObjectSpace.each_object(String) { |the_string| puts the_string } ##+obj
25 | }
26 | end
27 | end
28 |
29 | describe 'Prime' do
30 | it 'should have an each method' do
31 | require 'mathn'
32 | # Warning: According to Euclid, this never stops...
33 | Prime.each {|x| break if x > 100 }
34 | end
35 | end
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/18/Rakefile:
--------------------------------------------------------------------------------
1 | require '../utils/tasks.rb'
2 |
--------------------------------------------------------------------------------
/18/doc_with_load_save.rb:
--------------------------------------------------------------------------------
1 | require '../code/doc3'
2 |
3 | class Logger
4 | end
5 |
6 | class Document
7 |
8 | class << self
9 | attr_accessor :load_fail, :save_fail
10 | end
11 |
12 | def self.load( path )
13 | raise 'document failed' if @load_fail
14 | new( path, 'russ', '' )
15 | end
16 |
17 | def save
18 | raise 'document failed' if self.class.save_fail
19 | end
20 | end
21 |
22 |
--------------------------------------------------------------------------------
/18/ex_1_simple_load_save_spec.rb:
--------------------------------------------------------------------------------
1 | require 'doc_with_load_save'
2 |
3 | class SomeApplication ##(main
4 | # ...
5 |
6 | def do_something
7 | doc = Document.load( 'resume.txt' )
8 |
9 | # Do something interesting with the document.
10 |
11 | doc.save
12 | end
13 | end ##main)
14 |
15 |
16 | describe SomeApplication do
17 | it 'should just work' do
18 | SomeApplication.new.do_something
19 | end
20 | end
21 |
--------------------------------------------------------------------------------
/18/ex_2_simple_with_logging_spec.rb:
--------------------------------------------------------------------------------
1 | require 'doc_with_load_save'
2 |
3 |
4 | class SomeApplication ##(main
5 |
6 | def initialize( logger )
7 | @logger = logger
8 | end
9 |
10 | def do_something
11 | @logger.debug( 'Starting Document load' )
12 | doc = Document.load( 'resume.txt' )
13 | @logger.debug( 'Completed Document load' )
14 |
15 | # Do something interesting with the document.
16 |
17 | @logger.debug( 'Starting Document save' )
18 | doc.save
19 | @logger.debug( 'Completed Document save' )
20 | end
21 | end ##main)
22 |
23 | describe SomeApplication do
24 |
25 | before :each do
26 | Document.load_fail = Document.save_fail = false
27 | end
28 |
29 | it 'should work' do
30 | logger = mock
31 | logger.should_receive( :debug ).exactly(4).times
32 | SomeApplication.new( logger ).do_something
33 | end
34 | end
35 |
--------------------------------------------------------------------------------
/18/ex_3_load_save_with_logging_spec.rb:
--------------------------------------------------------------------------------
1 | require 'doc_with_load_save'
2 |
3 |
4 | class SomeApplication ##(main
5 |
6 | # Rest of the class omitted...
7 |
8 | def do_something
9 | begin
10 | @logger.debug( 'Starting Document load' )
11 | @doc = Document.load( 'resume.txt' )
12 | @logger.debug( 'Completed Document load' )
13 | rescue
14 | @logger.error( 'Load failed!!' )
15 | raise
16 | end
17 |
18 | # Do something with the document...
19 |
20 | begin
21 | @logger.debug( 'Starting Document save' )
22 | @doc.save
23 | @logger.debug( 'Completed Document save' )
24 | rescue
25 | @logger.error( 'Save failed!!' )
26 | raise
27 | end
28 | end
29 | end ##main)
30 |
31 |
32 | class SomeApplication
33 |
34 | def initialize( logger )
35 | @logger = logger
36 | end
37 | end
38 |
39 | load 'some_application_examples.rb'
40 |
--------------------------------------------------------------------------------
/18/ex_6_degenerative_xaround_spec.rb:
--------------------------------------------------------------------------------
1 |
2 | class SomeApplication
3 | def log_before( description ) ##(before
4 | @logger.debug( "Starting #{description}" )
5 | yield
6 | end ##before)
7 |
8 |
9 | def log_after( description ) ##(after
10 | yield
11 | @logger.debug( "Done #{description}" )
12 | end ##after)
13 | end
14 |
15 | class SomeApplication
16 | def initialize( logger )
17 | @logger = logger
18 | end
19 | end
20 |
21 | describe SomeApplication do
22 |
23 | it 'should have a propert log_before' do
24 | logger = mock
25 | logger.should_receive(:debug).exactly(1).times
26 | SomeApplication.new(logger).log_before('test') {}
27 | end
28 |
29 | it 'should have a propert log_after' do
30 | logger = mock
31 | logger.should_receive(:debug).exactly(1).times
32 | SomeApplication.new(logger).log_after('test') {}
33 | end
34 |
35 | end
36 |
--------------------------------------------------------------------------------
/18/ex_8_bogus_object_spec.rb:
--------------------------------------------------------------------------------
1 |
2 | require 'doc_with_load_save'
3 |
4 | class SomeApplication ##(main
5 |
6 | # Rest of the class omitted...
7 |
8 | def do_something
9 | with_logging('load', nil) { @doc = Document.load( 'book' ) }
10 |
11 | # Do something with the document...
12 |
13 | with_logging('save', @doc) { |the_object| the_object.save }
14 | end
15 |
16 |
17 | def with_logging(description, the_object)
18 | begin
19 | @logger.debug( "Starting #{description}" )
20 | yield( the_object )
21 | @logger.debug( "Completed #{description}" )
22 | rescue
23 | @logger.error( "#{description} failed!!")
24 | raise
25 | end
26 | end
27 | end ##main)
28 |
29 |
30 | class SomeApplication
31 | def initialize( logger )
32 | @logger = logger
33 | end
34 | end
35 |
36 |
37 | load 'some_application_examples.rb'
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/18/ex_8a_with_database_spec.rb:
--------------------------------------------------------------------------------
1 | class Database
2 | end
3 |
4 |
5 | class SomeApplication
6 | def with_database_connection( connection_info ) ##(main
7 | connection = Database.new( connection_info )
8 | begin
9 | yield( connection )
10 | ensure
11 | connection.close
12 | end
13 | end ##main)
14 | end
15 |
16 | describe SomeApplication do
17 |
18 | it 'should create and close a new database connection' do
19 | connection = mock
20 | connection.should_receive(:close)
21 | connection.should_receive(:query)
22 | Database.should_receive(:new).with('info').and_return(connection)
23 |
24 | app = SomeApplication.new
25 | app.with_database_connection('info') {|c| c.query}
26 | end
27 | end
28 |
29 |
--------------------------------------------------------------------------------
/18/ex_9_return_value_spec.rb:
--------------------------------------------------------------------------------
1 | require 'doc_with_load_save'
2 |
3 |
4 | class SomeApplication
5 |
6 | # Rest of the class omitted...
7 |
8 | def with_logging(description) ##(main
9 | begin
10 | @logger.debug( "Starting #{description}" )
11 | return_value = yield
12 | @logger.debug( "Completed #{description}" )
13 | return_value
14 | rescue
15 | @logger.error( "#{description} failed!!")
16 | raise
17 | end
18 | end ##main)
19 | end
20 |
21 | class SomeApplication
22 | def initialize( logger )
23 | @logger = logger
24 | end
25 | end
26 |
27 |
28 | describe SomeApplication do
29 | it "should have a working silly method" do
30 | logger = mock
31 | logger.should_receive(:debug).exactly(2).times
32 | SomeApplication.new(logger).with_logging('42') { 42 }.should == 42
33 | end
34 | end
35 |
--------------------------------------------------------------------------------
/18/some_application_examples.rb:
--------------------------------------------------------------------------------
1 | describe SomeApplication do
2 |
3 | before :each do
4 | Document.load_fail = Document.save_fail = false
5 | end
6 |
7 | it 'should do the proper logging when no exceptions are raised' do
8 | logger = mock
9 | logger.should_receive(:debug).exactly(4).times
10 | SomeApplication.new(logger).do_something
11 | end
12 |
13 | it 'should do the proper logging when the save fails' do
14 | logger = mock
15 | logger.should_receive(:debug).exactly(3).times
16 | logger.should_receive(:error).once
17 | Document.save_fail = true
18 | lambda { SomeApplication.new(logger).do_something }.should raise_error
19 | end
20 |
21 | it 'should do the proper logging when the load fails' do
22 | logger = mock
23 | logger.should_receive(:debug).exactly(1).times
24 | logger.should_receive(:error).once
25 | Document.load_fail = true
26 | lambda { SomeApplication.new(logger).do_something }.should raise_error
27 | end
28 | end
29 |
--------------------------------------------------------------------------------
/19/Rakefile:
--------------------------------------------------------------------------------
1 | require '../utils/tasks.rb'
2 |
--------------------------------------------------------------------------------
/19/doc_block_listeners.rb:
--------------------------------------------------------------------------------
1 | require '../code/doc3'
2 |
3 | class Document ##(main
4 |
5 | # Most of the class omitted...
6 |
7 | def on_save( &block )
8 | @save_listener = block
9 | end
10 |
11 | def on_load( &block )
12 | @load_listener = block
13 | end
14 |
15 | def load( path )
16 | @content = File.read( path )
17 | @load_listener.call( self, path ) if @load_listener
18 | end
19 |
20 | def save( path )
21 | File.open( path, 'w' ) { |f| f.print( @contents ) }
22 | @save_listener.call( self, path ) if @save_listener
23 | end
24 | end ##main)
25 |
--------------------------------------------------------------------------------
/19/ex_1_explicit_blocks_spec.rb:
--------------------------------------------------------------------------------
1 | require '../utils/rspec_utils'
2 |
3 | def run_that_block( &that_block ) ##(run_that_block
4 | puts "About to run the block"
5 | that_block.call
6 | puts "Done running the block"
7 | end ##run_that_block)
8 |
9 | def run_block_with_check( &that_block )
10 | that_block.call if that_block ##+check_block
11 | end
12 |
13 | describe 'explicit blocks' do
14 | it 'should call the block' do
15 | out = output_of { run_that_block {puts "hello"} }
16 | out.should match( /About.*hello.*Done/m )
17 | end
18 |
19 | it 'should check that a block is supplied' do
20 | run_block_with_check
21 | out = output_of { run_block_with_check { puts 'hello' } }
22 | out.should == "hello\n"
23 | end
24 | end
25 |
--------------------------------------------------------------------------------
/19/ex_4_block_load_save_spec.rb:
--------------------------------------------------------------------------------
1 |
2 | require '../code/doc3'
3 | require '../utils/rspec_utils'
4 |
5 | require 'doc_block_listeners'
6 |
7 | describe Document do
8 | it 'should comment on what is going on' do
9 | my_doc = Document.new( 'Block Based Example', 'russ', '' ) ##(main
10 |
11 | my_doc.on_load do |doc|
12 | puts "Hey, I've been loaded!"
13 | end
14 |
15 | my_doc.on_save do |doc|
16 | puts "Hey, I've been saved!"
17 | end ##main)
18 |
19 | save_out = output_of { my_doc.save("example.txt") }
20 | load_out = output_of { my_doc.load("example.txt") }
21 |
22 | puts save_out
23 | puts load_out
24 | save_out.should match(/Hey.*saved/m)
25 | load_out.should match(/Hey.*loaded/m)
26 | end
27 | end
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/19/ex_5_archival_doc_spec.rb:
--------------------------------------------------------------------------------
1 | require '../utils/rspec_utils'
2 |
3 |
4 | class ArchivalDocument ##(main
5 | attr_reader :title, :author
6 |
7 | def initialize(title, author, path)
8 | @title = title
9 | @author = author
10 | @path = path
11 | end
12 |
13 | def content
14 | @content ||= File.read( @path )
15 | end
16 | end ##main)
17 |
18 |
19 |
20 | describe ArchivalDocument do
21 | before :each do
22 | File.open( 'archive.txt', 'w' ) {|f| f.puts("hello out there")}
23 | end
24 |
25 | it 'know how to load from a file' do
26 | doc = ArchivalDocument.new( 'Archive doc', 'russ', 'archive.txt' )
27 | doc.instance_variable_get(:@content).should == nil
28 | doc.content.should == "hello out there\n"
29 | doc.instance_variable_get(:@content).should_not == nil
30 | File.delete('archive.txt')
31 | doc.content.should == "hello out there\n"
32 | end
33 | end
34 |
35 |
--------------------------------------------------------------------------------
/19/ex_8_big_array_spec.rb:
--------------------------------------------------------------------------------
1 | require 'doc_block_listeners'
2 |
3 | def some_method(doc) ##(main
4 | big_array = Array.new(10000000)
5 |
6 | # Do something with big_array...
7 |
8 | doc.on_load do |d|
9 | puts "Hey, I've been loaded!"
10 | end
11 | end ##main)
12 |
13 | describe 'some_method' do
14 | it 'should just work' do
15 | doc = Document.new( 'Block Based Example', 'russ', '' )
16 | some_method(doc)
17 | end
18 | end
19 |
--------------------------------------------------------------------------------
/19/ex_8a_array_no_block_spec.rb:
--------------------------------------------------------------------------------
1 | require 'doc_block_listeners'
2 |
3 | def some_method(doc) ##(main
4 | big_array = Array.new(10000000)
5 |
6 | # Do something with big_array...
7 |
8 | end ##main)
9 |
10 | describe 'some_method' do
11 | it 'should just work' do
12 | doc = Document.new( 'Block Based Example', 'russ', '' )
13 | some_method(doc)
14 | end
15 | end
16 |
--------------------------------------------------------------------------------
/19/ex_8b_big_array_fixed_spec.rb:
--------------------------------------------------------------------------------
1 | require 'doc_block_listeners'
2 |
3 | def some_method(doc) ##(main
4 | big_array = Array.new(10000000)
5 |
6 | # Do something with big_array...
7 |
8 | # And now get rid of it!
9 |
10 | big_array = nil
11 |
12 | doc.on_load do |d|
13 | puts "Hey, I've been loaded!"
14 | end
15 | end ##main)
16 |
17 | describe 'some_method' do
18 | it 'should just work' do
19 | doc = Document.new( 'Block Based Example', 'russ', '' )
20 | some_method(doc)
21 | end
22 | end
23 |
--------------------------------------------------------------------------------
/19/ex_9_spec.rb:
--------------------------------------------------------------------------------
1 | require 'doc_block_listeners'
2 |
3 | describe Document do
4 | it "should know how many words it contains" do ##(main
5 | doc = Document.new('example', 'russ', 'hello world')
6 | doc.word_count.should == 2
7 | end ##main)
8 | end
9 |
--------------------------------------------------------------------------------
/19/example.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/russolsen/eloquent_ruby_code/a7e2a638ef9920a6f71d53529ac7801b6b594b93/19/example.txt
--------------------------------------------------------------------------------
/19/saveload.txt:
--------------------------------------------------------------------------------
1 | Hey I've been loaded!
2 | Hey, I've been saved!
3 |
--------------------------------------------------------------------------------
/20/Rakefile:
--------------------------------------------------------------------------------
1 | require '../utils/tasks.rb'
2 |
--------------------------------------------------------------------------------
/20/at_exit_demo.rb:
--------------------------------------------------------------------------------
1 | at_exit do ##(nice
2 | puts "Have a nice day."
3 | end ##nice)
4 |
5 |
6 | at_exit do ##(bye
7 | puts "Goodbye"
8 | end ##bye)
9 |
--------------------------------------------------------------------------------
/20/autoloader.rb:
--------------------------------------------------------------------------------
1 |
2 | class Object
3 | def self.const_missing( name )
4 | file_name = "#{name.to_s.downcase}"
5 | require file_name
6 | raise "Undefined constant: #{name}" unless const_defined?(name)
7 | const_get(name)
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/20/autoloader_spec.rb:
--------------------------------------------------------------------------------
1 | ##
2 | require 'autoloader'
3 |
4 | describe 'autoloading example' do
5 |
6 | it "should load classes automatically by filename" do
7 | ##start
8 | today = Date.new
9 | fruit = Set.new( [ 'apple', 'orange', 'blueberry' ] )
10 | ##end
11 | end
12 |
13 | end
14 |
--------------------------------------------------------------------------------
/20/bye.txt:
--------------------------------------------------------------------------------
1 | Goodbye
2 | Have a nice day.
3 |
--------------------------------------------------------------------------------
/20/document_reader.rb:
--------------------------------------------------------------------------------
1 | require 'pp'
2 |
3 | class DocumentReader ##(doc
4 |
5 | class << self
6 | attr_reader :reader_classes
7 | end
8 |
9 | @reader_classes = []
10 |
11 | def self.read(path)
12 | reader = reader_for(path)
13 | return nil unless reader
14 | reader.read(path)
15 | end
16 |
17 | def self.reader_for(path)
18 | reader_class = DocumentReader.reader_classes.find do |klass|
19 | klass.can_read?(path)
20 | end
21 | return reader_class.new(path) if reader_class
22 | nil
23 | end
24 |
25 | # One critical bit omitted, but stay tuned...
26 | end ##doc)
27 |
28 | class DocumentReader
29 |
30 | # ... the vital missing piece ##(vital
31 |
32 | def self.inherited(subclass)
33 | DocumentReader.reader_classes << subclass
34 | end ##vital)
35 | end
36 |
--------------------------------------------------------------------------------
/20/ex_1_inherit_spec.rb:
--------------------------------------------------------------------------------
1 | require '../utils/rspec_utils'
2 |
3 | describe 'inherit example' do
4 | it 'should produce the right output' do
5 | out = output_of {
6 | load 'inherited_demo.rb'
7 | }
8 |
9 | out.should match(/.*ChildClassOne.*subclass.*SimpleBaseClass/)
10 |
11 | File.write( 'inherit.txt', out )
12 | end
13 |
14 | end
15 |
--------------------------------------------------------------------------------
/20/ex_2_included_spec.rb:
--------------------------------------------------------------------------------
1 | require '../utils/rspec_utils'
2 |
3 | module WritingQuality ##(wq
4 | def self.included(klass)
5 | puts "Hey, I've been included in #{klass}"
6 | end
7 |
8 | def number_of_cliches
9 | # Body of method omitted...
10 | end
11 | end ##wq)
12 |
13 | class Dummy
14 | public_class_method :include
15 | end
16 |
17 | describe WritingQuality do
18 | it 'should squak when you include it' do
19 | out = output_of { Dummy.include(WritingQuality) }
20 | out.should match( /Hey/ )
21 | end
22 | end
23 |
--------------------------------------------------------------------------------
/20/ex_3_extend_include_spec.rb:
--------------------------------------------------------------------------------
1 | module UsefulInstanceMethods ##(main
2 | def an_instance_method
3 | end
4 | end
5 |
6 | module UsefulClassMethods
7 | def a_class_method
8 | end
9 | end
10 |
11 | class Host
12 | include UsefulInstanceMethods
13 | extend UsefulClassMethods
14 | end ##main)
15 |
16 | describe Host do
17 | it 'should include UsefulInstanceMethods' do
18 | h = Host.new
19 | h.an_instance_method
20 | end
21 |
22 | it 'should have the class method' do
23 | Host.a_class_method
24 | end
25 | end
26 |
--------------------------------------------------------------------------------
/20/ex_4_include_with_auto_extend_spec.rb:
--------------------------------------------------------------------------------
1 |
2 |
3 | module UsefulMethods ##(main
4 | module ClassMethods
5 | def a_class_method
6 | end
7 | end
8 |
9 | def self.included( host_class )
10 | host_class.extend( ClassMethods )
11 | end
12 |
13 | def an_instance_method
14 | end
15 |
16 | # Rest of the module deleted...
17 | end
18 |
19 | class Host
20 | include UsefulMethods
21 | end ##main)
22 |
23 | describe Host do
24 | it 'should include InstanceMethods' do
25 | h = Host.new
26 | h.an_instance_method
27 | end
28 |
29 | it 'should have the class method' do
30 | Host.a_class_method
31 | end
32 | end
33 |
--------------------------------------------------------------------------------
/20/ex_4a_exit_spec.rb:
--------------------------------------------------------------------------------
1 | require '../utils/rspec_utils'
2 |
3 |
4 | describe 'at_exit demo' do
5 | it 'should print the right stuff' do
6 | out = `ruby at_exit_demo.rb`
7 | out.should match( /Goodbye.*Have a/m)
8 | File.write( 'bye.txt', out )
9 | end
10 | end
11 |
--------------------------------------------------------------------------------
/20/ex_5_trace_spec.rb:
--------------------------------------------------------------------------------
1 | require '../utils/rspec_utils'
2 |
3 |
4 | describe 'trace demo' do
5 | it 'should print the right stuff' do
6 | out = `ruby trace_func_demo.rb`
7 | out.size.should > 5000
8 | lines = out.split("\n")
9 | lines = lines[0..7]
10 | File.write( 'trace.txt', lines.join("\n" ) )
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/20/ex_6_when_spec.rb:
--------------------------------------------------------------------------------
1 |
2 | require 'document_reader'
3 |
4 | class DocumentReader ##(main
5 | # Stuff omitted...
6 | end
7 |
8 |
9 | class PlainTextReader < DocumentReader
10 | # Stuff omitted...
11 | end
12 |
13 | # inherited method for PlainTextReader goes off about now...
14 |
15 | class YAMLReader < DocumentReader
16 | # Stuff omitted...
17 | end
18 |
19 | # inherited method for YAMLReader goes off about now... ##main)
20 |
21 | describe 'inherit description' do
22 | it 'should just be syntax. correct' do
23 | PlainTextReader.superclass.should == DocumentReader
24 | YAMLReader.superclass.should == DocumentReader
25 | end
26 | end
27 |
--------------------------------------------------------------------------------
/20/ex_7_unexpected_inherit_spec.rb:
--------------------------------------------------------------------------------
1 | require 'readers'
2 |
3 | class AsianDocumentReader < DocumentReader ##(classes
4 | # Lots of code for dealing with Asian languages...
5 | end
6 |
7 | class JapaneseDocumentReader < AsianDocumentReader
8 | # Lots of stuff omitted...
9 | end
10 |
11 | class ChineseDocumentReader < AsianDocumentReader
12 | # Lots of stuff omitted...
13 | end ##classes)
14 |
15 | class AsianDocumentReader < DocumentReader ##(fix
16 | def self.can_read?(path)
17 | false
18 | end
19 |
20 | # Lots of code for dealing with Asian languages...
21 | end ##fix)
22 |
23 |
24 | describe DocumentReader do
25 | it 'should have an entry for asian documents' do
26 | readers = DocumentReader.instance_variable_get( :@reader_classes )
27 | readers.size.should == 6
28 | readers.should include(AsianDocumentReader)
29 | end
30 | end
31 |
--------------------------------------------------------------------------------
/20/inherit.txt:
--------------------------------------------------------------------------------
1 | Hey ChildClassOne is now a subclass of SimpleBaseClass!
2 |
--------------------------------------------------------------------------------
/20/inherited_demo.rb:
--------------------------------------------------------------------------------
1 | class SimpleBaseClass ##(base
2 | def self.inherited( new_subclass )
3 | puts "Hey #{new_subclass} is now a subclass of #{self}!"
4 | end
5 | end ##base)
6 |
7 |
8 | class ChildClassOne < SimpleBaseClass ##(child
9 | end ##child)
10 |
--------------------------------------------------------------------------------
/20/plain.txt:
--------------------------------------------------------------------------------
1 | Garp
2 | Irving
3 | Odd odd odd
4 |
--------------------------------------------------------------------------------
/20/plaintext_reader.rb:
--------------------------------------------------------------------------------
1 | class PlainTextReader < DocumentReader ##(plain
2 | def self.can_read?(path)
3 | /.*\.txt/ =~ path
4 | end
5 |
6 | def initialize(path)
7 | @path = path
8 | end
9 |
10 | def read(path)
11 | File.open(path) do |f|
12 | title = f.readline.chomp
13 | author = f.readline.chomp
14 | content = f.read.chomp
15 | Document.new( title, author, content )
16 | end
17 | end
18 | end ##plain)
19 |
--------------------------------------------------------------------------------
/20/readers.rb:
--------------------------------------------------------------------------------
1 | require '../code/doc3'
2 |
3 | require 'document_reader' ##(main
4 |
5 | require 'plaintext_reader' # inherited fires for PlainTextReader
6 | require 'xml_reader' # inherited fires for XMLReader
7 | require 'yaml_reader' # inherited fires for YAMLReader ##main)
8 |
--------------------------------------------------------------------------------
/20/trace.txt:
--------------------------------------------------------------------------------
1 | c-return in trace_func_demo.rb/5 set_trace_func Kernel
2 | line in trace_func_demo.rb/10
3 | c-call in trace_func_demo.rb/10 require Kernel
4 | c-return in trace_func_demo.rb/10 require Kernel
5 | line in trace_func_demo.rb/11
6 | c-call in trace_func_demo.rb/11 require Kernel
7 | c-call in trace_func_demo.rb/11 set_encoding IO
8 | c-return in trace_func_demo.rb/11 set_encoding IO
--------------------------------------------------------------------------------
/20/trace_func_demo.rb:
--------------------------------------------------------------------------------
1 | proc_object = proc do |event, file, line, id, binding, klass|
2 | puts "#{event} in #{file}/#{line} #{id} #{klass}"
3 | end
4 |
5 | set_trace_func(proc_object)
6 |
7 | # Since date is apparently already loaded, we will also
8 | # load treetop to generate some serious tracing.
9 | #
10 | require 'date'
11 | require 'treetop'
12 |
--------------------------------------------------------------------------------
/20/xml_reader.rb:
--------------------------------------------------------------------------------
1 | class XMLReader < DocumentReader
2 | def self.can_read?(path)
3 | /.*\.xml/ =~ path
4 | end
5 |
6 | def initialize(path)
7 | @path = path
8 | end
9 |
10 | def read(path)
11 | # Lots of complicated XML stuff omitted
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/20/yaml_reader.rb:
--------------------------------------------------------------------------------
1 | class YAMLReader < DocumentReader
2 | def self.can_read?(path)
3 | /.*\.yaml/ =~ path
4 | end
5 |
6 | def initialize(path)
7 | @path = path
8 | end
9 |
10 | def read(path)
11 | # Lots of simple YAML stuff omitted
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/21/Rakefile:
--------------------------------------------------------------------------------
1 | require '../utils/tasks.rb'
2 |
3 | CLEAN.include(%w{guess.txt document.error repeat.txt})
4 |
--------------------------------------------------------------------------------
/21/ex_1_spec.rb:
--------------------------------------------------------------------------------
1 | require '../code/doc3'
2 |
3 | describe 'calling the wrong method' do
4 |
5 | it 'should just blow up' do
6 | lambda {
7 | # Error: the method is content, not text! ##(main
8 |
9 | doc = Document.new('Titanic', 'Cameron', 'Sail, crash, sink')
10 | puts "The text is #{doc.text}" ##main)
11 | }.should raise_error
12 |
13 | end
14 |
15 | end
16 |
--------------------------------------------------------------------------------
/21/ex_2_repeat_spec.rb:
--------------------------------------------------------------------------------
1 | require '../utils/rspec_utils'
2 |
3 | class RepeatBackToMe ##(main
4 | def method_missing( method_name, *args )
5 | puts "Hey, you just called the #{method_name} method"
6 | puts "With these arguments: #{args.join(' ')}"
7 | puts "But there ain't no such method"
8 | end
9 | end ##main)
10 |
11 |
12 | describe RepeatBackToMe do
13 |
14 | it 'should output the method' do
15 | out = output_of {
16 | repeat = RepeatBackToMe.new ##(example
17 | repeat.hello( 1, 2, 3 )
18 | repeat.good_bye( "for", "now" ) ##example)
19 | }
20 |
21 | out.should match( /^Hey.*hello method.*1 2 3.*good_by.*now$/m )
22 | File.write( 'repeat.txt', out )
23 | end
24 |
25 |
26 | end
27 |
--------------------------------------------------------------------------------
/21/ex_3_doc_missing_spec.rb:
--------------------------------------------------------------------------------
1 | require '../utils/rspec_utils'
2 | require '../code/doc3'
3 |
4 | class Document ##(main
5 | # Most of the class omitted...
6 |
7 | def method_missing( method_name, *args )
8 | msg = %Q{
9 | You tried to call the method #{method_name}
10 | on an instance of Document. There is no such method.
11 | }
12 | raise msg
13 | end
14 | end ##main)
15 |
16 | describe Document do
17 |
18 | it 'should complain correctly' do
19 | doc = Document.new('Titanic', 'Cameron', 'Sail, crash, sink')
20 | begin
21 | puts "The text is #{doc.text}"
22 | rescue
23 | $!.message.should match( /.*You tried.*method text.*no such.*/m )
24 | end
25 | end
26 |
27 |
28 | end
29 |
--------------------------------------------------------------------------------
/21/ex_4_doc_to_file_spec.rb:
--------------------------------------------------------------------------------
1 | require '../utils/rspec_utils'
2 | require '../code/doc3'
3 |
4 | class Document ##(main
5 | # Most of the class omitted...
6 |
7 | def method_missing( method_name, *args )
8 | File.open( 'document.error', 'a' ) do |f|
9 | f.puts( "Bad method called: #{method_name}" )
10 | f.puts( "with #{args.size} arguments" )
11 | end
12 | super
13 | end
14 | end ##main)
15 |
16 | describe Document do
17 |
18 | it 'should write the error to a file' do
19 | File.delete('document.error') if File.exist?('document.error')
20 |
21 | doc = Document.new('Titanic', 'Cameron', 'Sail, crash, sink')
22 |
23 | lambda {
24 | puts "The text is #{doc.text}"
25 | }.should raise_error
26 |
27 | out = File.read( 'document.error' )
28 | out.should match( /.*Bad method called.*text*/m )
29 | end
30 |
31 |
32 | end
33 |
--------------------------------------------------------------------------------
/21/ex_6_autoload_const_spec.rb:
--------------------------------------------------------------------------------
1 | require '../utils/rspec_utils'
2 | require '../code/doc3'
3 |
4 | class Document ##(main
5 | # Most of the class omitted...
6 |
7 | def self.const_missing( const_name )
8 | msg = %Q{
9 | You tried to reference the constant #{const_name}
10 | There is no such constant in the Document class.
11 | }
12 | raise msg
13 | end
14 | end ##main)
15 |
16 | describe Document do
17 |
18 | it 'should complain correctly' do
19 | doc = Document.new('Titanic', 'Cameron', 'Sail, crash, sink')
20 | begin
21 | Document::FooBar
22 | rescue
23 | $!.message.should match( /.*You tried.*constant FooBar.*no such.*/m )
24 | end
25 | end
26 |
27 |
28 | end
29 |
--------------------------------------------------------------------------------
/21/ex_6_const_missing_spec.rb:
--------------------------------------------------------------------------------
1 | require '../utils/rspec_utils'
2 | require '../code/doc3'
3 |
4 | class Document ##(main
5 | # Most of the class omitted...
6 |
7 | def self.const_missing( const_name )
8 | msg = %Q{
9 | You tried to reference the constant #{const_name}
10 | There is no such constant in the Document class.
11 | }
12 | raise msg
13 | end
14 | end ##main)
15 |
16 | describe Document do
17 |
18 | it 'should complain correctly' do
19 | doc = Document.new('Titanic', 'Cameron', 'Sail, crash, sink')
20 | begin
21 | Document::FooBar
22 | rescue
23 | $!.message.should match( /.*You tried.*constant FooBar.*no such.*/m )
24 | end
25 | end
26 |
27 |
28 | end
29 |
--------------------------------------------------------------------------------
/21/ex_7_autoload_const_spec.rb:
--------------------------------------------------------------------------------
1 | require '../utils/rspec_utils'
2 |
3 | class AutoLoad
4 | def self.const_missing( name ) ##(main
5 | file_name = "#{name.to_s.downcase}"
6 | require file_name
7 | raise "Undefined: #{name}" unless const_defined?(name)
8 | const_get(name)
9 | end ##main)
10 | end
11 |
12 | describe AutoLoad do
13 |
14 | it 'should autoload files' do
15 | clazz = AutoLoad::Example
16 | clazz.class.should == Class
17 | end
18 |
19 | it 'should blow up on undefined files' do
20 | lambda { clazz = AutoLoad::FooBar }.should raise_error
21 | end
22 |
23 | end
24 |
--------------------------------------------------------------------------------
/21/example.rb:
--------------------------------------------------------------------------------
1 | # Example Ruby class for autoloading
2 |
3 |
4 | class Example
5 | end
6 |
--------------------------------------------------------------------------------
/22/Rakefile:
--------------------------------------------------------------------------------
1 | require '../utils/tasks.rb'
2 |
3 | CLEAN.include(%w{hare.txt to_s.txt})
4 |
5 |
--------------------------------------------------------------------------------
/22/ssdoc_mm.rb:
--------------------------------------------------------------------------------
1 | class SuperSecretDocument ##(main
2 | def initialize(original_document, time_limit_seconds)
3 | @original_document = original_document
4 | @time_limit_seconds = time_limit_seconds
5 | @create_time = Time.now
6 | end
7 |
8 | def time_expired?
9 | Time.now - @create_time >= @time_limit_seconds
10 | end
11 |
12 | def check_for_expiration
13 | raise 'Document no longer available' if time_expired?
14 | end
15 |
16 | def method_missing(name, *args)
17 | check_for_expiration
18 | @original_document.send(name, *args) ##+send
19 | end
20 | end ##main)
21 |
--------------------------------------------------------------------------------
/23/Rakefile:
--------------------------------------------------------------------------------
1 | require '../utils/tasks.rb'
2 |
3 | CLEAN.include(%w{conflict.txt})
4 |
5 |
--------------------------------------------------------------------------------
/23/ex_formletter2_spec.rb:
--------------------------------------------------------------------------------
1 | require '../utils/rspec_utils'
2 | require '../code/doc3'
3 |
4 |
5 | class FormLetter < Document ##(main
6 |
7 | def replace_word( old_word, new_word )
8 | @content.gsub!( old_word, "#{new_word}" )
9 | end
10 |
11 | def replace_firstname( new_first_name )
12 | replace_word( 'FIRSTNAME', new_first_name )
13 | end
14 |
15 | def replace_lastname( new_last_name )
16 | replace_word( 'LASTNAME', new_last_name )
17 | end
18 | end ##main)
19 |
20 | describe 'FormLetter with conv. methods' do
21 | it "should know how to replace fn and ln" do
22 | fl = FormLetter.new( "form", "russ", "FIRSTNAME LASTNAME" )
23 | fl.replace_firstname( 'Fred' )
24 | fl.replace_lastname( 'Flip' )
25 | fl.content.should == 'Fred Flip'
26 | end
27 | end
28 |
--------------------------------------------------------------------------------
/23/ostruct_spec.rb:
--------------------------------------------------------------------------------
1 | require 'ostruct'
2 |
3 | describe OpenStruct do
4 | it 'should just work' do
5 | author = OpenStruct.new
6 | author.first_name = 'Stephen'
7 | author.last_name = 'Hawking'
8 | puts author.first_name
9 | puts author.last_name
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/24/Rakefile:
--------------------------------------------------------------------------------
1 | require '../utils/tasks.rb'
2 |
--------------------------------------------------------------------------------
/24/document.rb:
--------------------------------------------------------------------------------
1 | # Dummy document file, used just to make the requires in
2 | # examples look right.
3 |
--------------------------------------------------------------------------------
/24/ex_1_spec.rb:
--------------------------------------------------------------------------------
1 | require '../code/doc4'
2 | require '../utils/rspec_utils'
3 |
4 | describe 'initial examples in chapter' do
5 | it 'should demo simple vars correctly' do
6 | name = 'Issac' ##+name1
7 | name = 'Asimov' ##+name2
8 |
9 | name.should == 'Asimov'
10 | end
11 |
12 | it 'should demo the average_word_length method correctly' do
13 | cover_letter = Document.new( 'Letter', 'Russ', "Here's my resume" ) ##+cover
14 |
15 | avg = (
16 | cover_letter.average_word_length ##+avg_word_len
17 | )
18 | (avg - 4.666667).abs.should < 0.001
19 | end
20 |
21 | it 'should demo bad things with empty docs' do
22 | out = output_of {
23 | empty_doc = Document.new( 'Empty!', 'Russ', '' ) ##(empty
24 | puts empty_doc.average_word_length ##empty)
25 | }
26 | out.should == "NaN\n"
27 | end
28 | end
29 |
--------------------------------------------------------------------------------
/24/ex_alias_method_spec.rb:
--------------------------------------------------------------------------------
1 | require '../code/doc4'
2 |
3 | class Document ##(main
4 | # Stuff omitted...
5 |
6 | def word_count
7 | words.size
8 | end
9 |
10 | alias_method :number_of_words, :word_count
11 | alias_method :size_in_words, :word_count
12 |
13 | # Stuff omitted...
14 | end ##main)
15 |
16 | describe 'aliases' do
17 |
18 | it 'should provide a copy of the method' do
19 | doc = Document.new( 'example', 'russ', 'one two three' )
20 | doc.word_count.should == 3
21 | doc.word_count.should == doc.number_of_words
22 | doc.word_count.should == doc.size_in_words
23 | end
24 | end
25 |
--------------------------------------------------------------------------------
/24/ex_alias_patch_spec.rb:
--------------------------------------------------------------------------------
1 | require '../code/doc4'
2 |
3 | class String ##(string
4 | alias_method :old_addition, :+
5 |
6 | def +( other )
7 | if other.kind_of? Document
8 | new_content = self + other.content
9 | return Document.new(other.title, other.author, new_content)
10 | end
11 | old_addition(other)
12 | end
13 | end ##string)
14 |
15 | describe String do
16 | it 'should know how to add itself to a Document' do
17 | d1 = Document.new( 'example', 'russ', 'out there' )
18 | d2 = 'hello ' + d1
19 | d2.author.should == 'russ'
20 | d2.title.should == 'example'
21 | d2.content.should == 'hello out there'
22 | end
23 |
24 | it "should still be able to add" do
25 | ('aaa' + 'bbb').should == 'aaabbb'
26 | ('' + 'bbb').should == 'bbb'
27 | ('aaa' + '').should == 'aaa'
28 | end
29 |
30 | end
31 |
--------------------------------------------------------------------------------
/24/ex_fix_bug_spec.rb:
--------------------------------------------------------------------------------
1 | require '../code/doc4'
2 |
3 | require 'document' # Pull in original, broken class ##(main
4 |
5 | class Document
6 | def average_word_length
7 | return 0.0 if word_count == 0
8 | total = words.inject(0.0){ |result, word| word.size + result}
9 | total / word_count
10 | end
11 | end ##main)
12 |
13 |
14 | describe 'monkey patched document class' do
15 |
16 | it 'should return 0.0 for an empty document' do
17 | d = Document.new( 'empty', 'russ', '' )
18 | d.average_word_length.should == 0.0
19 | d.content = 'hello'
20 | d.average_word_length.should == 5.0
21 | end
22 | end
23 |
--------------------------------------------------------------------------------
/24/ex_no_wordcount_spec.rb:
--------------------------------------------------------------------------------
1 | require '../utils/rspec_utils'
2 | require '../code/doc4.rb'
3 |
4 | class Document ##(main
5 | remove_method :word_count
6 | end ##main)
7 |
8 |
9 | describe 'document with private word_count' do
10 | it 'should have a private wordcount method' do
11 | doc = Document.new( 'example', 'russ', 'hello world' )
12 | lambda { doc.word_count }.should raise_error
13 | end
14 | end
15 |
--------------------------------------------------------------------------------
/24/ex_private_wordcount_spec.rb:
--------------------------------------------------------------------------------
1 | require '../code/doc4.rb'
2 |
3 | class Document ##(main
4 | private :word_count
5 | end ##main)
6 |
7 | describe 'document with private word_count' do
8 | it 'should have a private wordcount method' do
9 | doc = Document.new( 'example', 'russ', 'hello world' )
10 | lambda { doc.word_count }.should raise_error
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/24/ex_public_wordcount_spec.rb:
--------------------------------------------------------------------------------
1 | require '../code/doc4.rb'
2 |
3 | class Document
4 | private :word_count
5 | end
6 |
7 | class Document ##(main
8 | public :word_count
9 | end ##main)
10 |
11 | describe 'document with private word_count' do
12 | it 'should have a private wordcount method' do
13 | doc = Document.new( 'example', 'russ', 'hello world' )
14 | doc.word_count
15 | end
16 | end
17 |
--------------------------------------------------------------------------------
/24/ex_string_patch_spec.rb:
--------------------------------------------------------------------------------
1 | require '../code/doc4'
2 |
3 | class String ##(string
4 | def +( other )
5 | if other.kind_of? Document
6 | new_content = self + other.content
7 | return Document.new(other.title, other.author, new_content)
8 | end
9 | result = self.dup
10 | result << other.to_str
11 | result
12 | end
13 | end ##string)
14 |
15 | describe String do
16 | it 'should know how to add itself to a Document' do
17 | d1 = Document.new( 'example', 'russ', 'out there' )
18 | d2 = 'hello ' + d1
19 | d2.author.should == 'russ'
20 | d2.title.should == 'example'
21 | d2.content.should == 'hello out there'
22 | end
23 |
24 | it "should still be able to add" do
25 | ('aaa' + 'bbb').should == 'aaabbb'
26 | ('' + 'bbb').should == 'bbb'
27 | ('aaa' + '').should == 'aaa'
28 | end
29 |
30 | end
31 |
--------------------------------------------------------------------------------
/25/Rakefile:
--------------------------------------------------------------------------------
1 | require '../utils/tasks.rb'
2 |
3 | CLEAN.include(%w{hello.txt junk.txt lessempty.txt second.txt self.txt})
4 | CLEAN.include(%w{foo.rb})
5 |
6 |
--------------------------------------------------------------------------------
/25/broken_encrypting_document.rb:
--------------------------------------------------------------------------------
1 | require '../code/doc3'
2 |
3 | ENCRYPTION_ENABLED = true
4 |
5 | class Document
6 |
7 | # Most of the class left behind...
8 |
9 | def self.enable_encryption( enabled ) ##(main
10 | if enabled
11 | def encrypt_string( string )
12 | string.tr( 'a-zA-Z', 'm-za-lM-ZA-L')
13 | end
14 | else
15 | def incrypt_string( string )
16 | string
17 | end
18 | end
19 | end ##main)
20 | enable_encryption( ENCRYPTION_ENABLED )
21 | end
22 |
--------------------------------------------------------------------------------
/25/encrypting_document.rb:
--------------------------------------------------------------------------------
1 | require '../code/doc3'
2 |
3 | ENCRYPTION_ENABLED = true ##(main
4 |
5 | class Document
6 |
7 | # Most of the class left behind...
8 |
9 | def self.enable_encryption( enabled )
10 | if enabled
11 | def encrypt_string( string )
12 | string.tr( 'a-zA-Z', 'm-za-lM-ZA-L')
13 | end
14 | else
15 | def encrypt_string( string )
16 | string
17 | end
18 | end
19 | end
20 |
21 | enable_encryption( ENCRYPTION_ENABLED )
22 | end ##main)
23 |
--------------------------------------------------------------------------------
/25/ex_1_mostly_spec.rb:
--------------------------------------------------------------------------------
1 | require '../utils/rspec_utils'
2 |
3 | describe 'class definition' do
4 | it 'should execute code inside of class statement' do
5 | out = output_of {
6 | class MostlyEmpty ##(hello_inside
7 | puts "hello from inside the class"
8 | end ##hello_inside)
9 | }
10 | out.should match(/hello from/)
11 | File.write( 'hello.txt', out )
12 | end
13 |
14 | it 'should make self the class inside of the def' do
15 | out = output_of {
16 | class MostlyEmpty ##(self_inside
17 | puts "The value of self is #{self}"
18 | end ##self_inside)
19 | }
20 | out.should match(/The value.*MostlyEmpty/)
21 | File.write( 'self.txt', out )
22 | end
23 |
24 | end
25 |
--------------------------------------------------------------------------------
/25/ex_2_one_step_spec.rb:
--------------------------------------------------------------------------------
1 | require '../utils/rspec_utils'
2 | require 'pp'
3 |
4 | describe 'class definition' do
5 | it 'should define methods one at a time' do
6 | out = output_of {
7 | class TheSameMethodTwice ##(main
8 |
9 | def do_something
10 | puts "first version"
11 | end
12 |
13 | # In between method definitions
14 |
15 | def do_something
16 | puts "second version"
17 | end
18 | end
19 |
20 | twice = TheSameMethodTwice.new
21 | twice.do_something ##main)
22 | }
23 | out.should match(/second version/)
24 | File.write( 'second.txt', out )
25 | end
26 |
27 | end
28 |
--------------------------------------------------------------------------------
/25/ex_3_sep_classes_spec.rb:
--------------------------------------------------------------------------------
1 | require '../utils/rspec_utils'
2 | require 'pp'
3 |
4 | describe 'class definition' do
5 | it 'should define methods one at a time' do
6 | out = output_of {
7 | class TheSameMethodTwice ##(main
8 | def do_something
9 | puts "first version"
10 | end
11 | end
12 |
13 | class TheSameMethodTwice
14 | def do_something
15 | puts "second version"
16 | end
17 | end ##main)
18 |
19 | smt = TheSameMethodTwice.new
20 | smt.do_something
21 | }
22 | out.should match(/second version/)
23 | end
24 |
25 | end
26 |
--------------------------------------------------------------------------------
/25/ex_3_twice_spec.rb:
--------------------------------------------------------------------------------
1 | require '../utils/rspec_utils'
2 | require 'pp'
3 |
4 | describe 'class definition' do
5 | it 'should define methods one at a time' do
6 | out = output_of {
7 | class LessEmpty ##(main
8 | pp instance_methods(false)
9 |
10 | def do_something
11 | puts "I'm doing something!"
12 | end
13 |
14 | pp instance_methods(false)
15 | end ##main)
16 | }
17 | out.should match(/\[\]\n\[:do_something\]/)
18 | File.write( 'lessempty.txt', out )
19 | end
20 |
21 | end
22 |
--------------------------------------------------------------------------------
/25/ex_5_toggle_encryption_spec.rb:
--------------------------------------------------------------------------------
1 | require 'encrypting_document'
2 |
3 | describe Document do ##(main
4 | before :each do
5 | @doc = Document.new( "test", "tester", "this is a test" )
6 | end
7 |
8 | it "should encrypt if encryption is enabled" do
9 | Document.enable_encryption( true )
10 | @doc.encrypt_string( 'abc' ).should_not == 'abc'
11 | end
12 |
13 | it "should not encrypt if encryption is disabled" do
14 | Document.enable_encryption( false ) ##+enable
15 | @doc.encrypt_string( 'abc' ).should == 'abc'
16 | end
17 | end ##main)
18 |
--------------------------------------------------------------------------------
/25/ex_6_char_at_spec.rb:
--------------------------------------------------------------------------------
1 | require '../code/doc3'
2 |
3 | class Document ##(main
4 | # Ruby 1.9 version
5 |
6 | def char_at( index )
7 | @content[ index ]
8 | end
9 | end ##main)
10 |
11 | describe Document do
12 | it 'should have a working char_at method' do
13 | d = Document.new( '', '', 'abcde' )
14 | d.char_at(0).should == 'a'
15 | d.char_at(1).should == 'b'
16 | d.char_at(2).should == 'c'
17 | d.char_at(3).should == 'd'
18 | d.char_at(4).should == 'e'
19 | end
20 | end
21 |
22 |
23 |
--------------------------------------------------------------------------------
/25/ex_7_char_at_switch_spec.rb:
--------------------------------------------------------------------------------
1 | require '../code/doc3'
2 |
3 | class Document ##(main
4 | # Lots of stuff omitted...
5 |
6 | if RUBY_VERSION >= '1.9'
7 | def char_at( index )
8 | @content[ index ]
9 | end
10 | else
11 | def char_at( index )
12 | @content[ index ].chr
13 | end
14 | end
15 | end ##main)
16 |
17 | describe Document do
18 | it 'should have a working char_at method' do
19 | d = Document.new( '', '', 'abcde' )
20 | d.char_at(0).should == 'a'
21 | d.char_at(1).should == 'b'
22 | d.char_at(2).should == 'c'
23 | d.char_at(3).should == 'd'
24 | d.char_at(4).should == 'e'
25 | end
26 | end
27 |
28 |
29 |
--------------------------------------------------------------------------------
/25/ex_8_reload_spec.rb:
--------------------------------------------------------------------------------
1 | require '../code/doc3'
2 | require '../utils/rspec_utils'
3 | require 'fileutils'
4 |
5 | describe Document do
6 | it 'should have a reload method' do
7 | FileUtils.cp 'reloadable_document.rb', 'foo.rb'
8 | load 'foo.rb'
9 | d = Document.new( '', '', '' )
10 | d.doit.should == 111
11 | File.write( 'foo.rb', File.read('foo.rb').sub('111','222') )
12 | Document.reload
13 | d.doit.should == 222
14 | end
15 | end
16 |
17 |
18 |
--------------------------------------------------------------------------------
/25/ex_9_better_reloadable_spec.rb:
--------------------------------------------------------------------------------
1 | require '../code/doc3'
2 | require '../utils/rspec_utils'
3 | require 'fileutils'
4 | require 'pp'
5 |
6 | describe Document do
7 | it 'should have a reload method' do
8 | FileUtils.cp 'reloadable_document2.rb', 'foo.rb'
9 | load 'foo.rb'
10 | d = Document.new( '', '', '' )
11 | d.doit.should == 111
12 |
13 | code = File.read('foo.rb')
14 | code.sub!('111','222')
15 | code.sub!( 'doit', 'zzz' )
16 |
17 | File.write( 'foo.rb', code )
18 | Document.reload
19 | d.zzz.should == 222
20 | Document.instance_methods.should_not include(:doit)
21 | end
22 | end
23 |
24 |
25 |
--------------------------------------------------------------------------------
/25/reloadable_document.rb:
--------------------------------------------------------------------------------
1 | require '../code/doc3'
2 |
3 | class Document ##(main
4 | def self.reload
5 | load( __FILE__ )
6 | end
7 |
8 | # Rest of the class omitted...
9 | end ##main)
10 |
11 | class Document
12 | def doit
13 | 111
14 | end
15 | end
16 |
--------------------------------------------------------------------------------
/25/reloadable_document2.rb:
--------------------------------------------------------------------------------
1 | require '../code/doc3'
2 |
3 | class Document ##(main
4 | def self.reload
5 | remove_instance_methods
6 | load( __FILE__ )
7 | end
8 |
9 | def self.remove_instance_methods
10 | instance_methods(false).each do |method|
11 | remove_method(method)
12 | end
13 | end
14 |
15 | # Rest of the class omitted...
16 | end ##main)
17 |
18 | class Document
19 | def doit
20 | 111
21 | end
22 | end
23 |
--------------------------------------------------------------------------------
/25/trouble_document.rb:
--------------------------------------------------------------------------------
1 | require '../code/doc3'
2 |
3 | ENCRYPTION_ENABLED = true ##(main
4 |
5 | # Broken!!
6 |
7 | class Document
8 |
9 | # Most of the class left behind...
10 |
11 | def self.enable_encryption( enabled )
12 | if enabled
13 | def encrypt_string( string )
14 | string.tr( 'a-zA-Z', 'm-za-lM-ZA-L')
15 | end
16 | else
17 | def encrypt_string( string )
18 | string
19 | end
20 | end
21 | end
22 | end ##main)
23 |
--------------------------------------------------------------------------------
/26/Rakefile:
--------------------------------------------------------------------------------
1 | require '../utils/tasks.rb'
2 |
--------------------------------------------------------------------------------
/26/disclaimer.txt:
--------------------------------------------------------------------------------
1 | This document is a deep, dark secret
2 |
--------------------------------------------------------------------------------
/26/ex_1_struc_doc_spec.rb:
--------------------------------------------------------------------------------
1 | require 'structured_document'
2 | require 'pp'
3 |
4 | describe StructuredDocument do
5 | it 'should actually work' do
6 | russ_cv = StructuredDocument.new( 'Resume', 'RO' ) do |cv| ##(russ_cv
7 | cv << Paragraph.new( :nimbus, 14, :bold, 'Russ Olsen' )
8 | cv << Paragraph.new( :nimbus, 12, :italic, '222 Rocky Way')
9 | cv << Paragraph.new( :nimbus, 12, :none, 'russ@russolsen.com')
10 | # .. and so on
11 | end ##russ_cv)
12 |
13 | russ_cv.paragraphs.first.text.should == 'Russ Olsen'
14 | russ_cv.paragraphs.first.font_name.should == :nimbus
15 | russ_cv.paragraphs.first.font_size.should == 14
16 | russ_cv.paragraphs.first.font_emphasis.should == :bold
17 |
18 | russ_cv.paragraphs[1].text.should match(/222.*/)
19 | russ_cv.paragraphs.last.text.should match(/@russolsen.com/)
20 | russ_cv.content.should match(/Russ.*Rocky.*olsen.com/m)
21 | end
22 | end
23 |
24 |
--------------------------------------------------------------------------------
/26/ex_4_meta_ins_spec.rb:
--------------------------------------------------------------------------------
1 | require 'structured_document'
2 | require 'structured_doc_eval'
3 | require 'pp'
4 |
5 |
6 | class Instructions < StructuredDocument ##(main
7 | paragraph_type( :introduction,
8 | :font_name => :arial,
9 | :font_size => 18,
10 | :font_emphasis => :italic )
11 |
12 | # And so on...
13 | end ##main)
14 |
15 |
16 | describe Instructions do
17 | it 'should have the proper methods' do
18 | Instructions.instance_methods.should include( :introduction )
19 | end
20 |
21 | it 'should produce working instruction instances' do
22 | i = Instructions.new( 'building a house', 'russ' )
23 | i.introduction( 'This is how you build a house' )
24 | i.introduction( 'carefully' )
25 |
26 | i.paragraphs.first.text.should match(/This is how/)
27 | i.paragraphs.last.font_size.should == 18
28 | i.paragraphs.last.font_emphasis.should == :italic
29 | end
30 | end
31 |
--------------------------------------------------------------------------------
/26/ex_4_question_spec.rb:
--------------------------------------------------------------------------------
1 | require 'structured_document'
2 | require 'pp'
3 |
4 |
5 | class StructuredDocument ##(main
6 | def self.paragraph_type( paragraph_name, options )
7 | # What do we do in here?
8 | end
9 |
10 | # ...
11 | end ##main)
12 |
13 |
14 | describe StructuredDocument do
15 | it 'should have the proper methods' do
16 | StructuredDocument.public_methods.should include( :paragraph_type )
17 | end
18 | end
19 |
--------------------------------------------------------------------------------
/26/ex_5_def_method_spec.rb:
--------------------------------------------------------------------------------
1 | require 'structured_document'
2 | require 'structured_doc_def_method'
3 | require 'pp'
4 |
5 |
6 | class Instructions < StructuredDocument
7 | paragraph_type( :introduction,
8 | :font_name => :arial,
9 | :font_size => 18,
10 | :font_emphasis => :bold )
11 |
12 | # And so on...
13 | end
14 |
15 |
16 | describe Instructions do
17 | it 'should have the proper methods' do
18 | Instructions.instance_methods.should include( :introduction )
19 | end
20 |
21 | it 'should produce working instruction instances' do
22 | i = Instructions.new( 'building a house', 'russ' )
23 | i.introduction( 'This is how you build a house' )
24 | i.introduction( 'carefully' )
25 |
26 | i.paragraphs.first.text.should match(/This is how/)
27 | i.paragraphs.last.font_size.should == 18
28 | i.paragraphs.last.font_emphasis.should == :bold
29 | end
30 |
31 | end
32 |
--------------------------------------------------------------------------------
/26/ex_8_attrs_spec.rb:
--------------------------------------------------------------------------------
1 | class Printer ##(printer
2 | attr_accessor :name
3 | end ##printer)
4 |
5 | describe Printer do
6 | it 'should have the correct accessors' do
7 | methods = Printer.instance_methods
8 | methods.should include(:name)
9 | methods.should include(:name=)
10 | end
11 | end
12 |
13 |
--------------------------------------------------------------------------------
/26/ex_8_dumb_attrs_spec.rb:
--------------------------------------------------------------------------------
1 | class Printer ##(printer
2 | def name
3 | @name
4 | end
5 |
6 | def name=(value)
7 | @name = value
8 | end
9 | end ##printer)
10 |
11 | describe Printer do
12 | it 'should have the correct accessors' do
13 | methods = Printer.instance_methods
14 | methods.should include(:name)
15 | methods.should include(:name=)
16 | end
17 |
18 | it 'should work' do
19 | p = Printer.new
20 | p.name.should == nil
21 | p.name = 'epson'
22 | p.name.should == 'epson'
23 | end
24 | end
25 |
26 |
--------------------------------------------------------------------------------
/26/ex_9_forwardable.rb:
--------------------------------------------------------------------------------
1 | require '../code/doc3'
2 | require '../utils/rspec_utils'
3 |
4 | require 'forwardable'
5 |
6 | class DocumentWrapper ##(main
7 | extend Forwardable
8 |
9 | def_delegators :@real_doc, :title, :author, :content
10 |
11 | def initialize( real_doc )
12 | @real_doc = real_doc
13 | end
14 | end ##main)
15 |
16 |
17 |
18 | describe DocumentWrapper do
19 | it 'should work' do
20 | real_doc = wrapped_doc = nil
21 |
22 | out = output_of {
23 | real_doc = Document.new( 'Two Cities', 'Dickens', 'It was...' ) ##(ex
24 | wrapped_doc = DocumentWrapper.new( real_doc )
25 |
26 | puts wrapped_doc.title
27 | puts wrapped_doc.author
28 | puts wrapped_doc.content ##ex)
29 | }
30 |
31 | out.should match(/Two.*Dickens.*Best/m)
32 |
33 | wrapped_doc.title.should == real_doc.title
34 | wrapped_doc.author.should == real_doc.author
35 | wrapped_doc.content.should == real_doc.content
36 | end
37 | end
38 |
--------------------------------------------------------------------------------
/26/forw.rb:
--------------------------------------------------------------------------------
1 | module Forwardable
2 | # Lots of code deleted...
3 |
4 | def def_instance_delegator(accessor, method, ali = method)
5 | str = %{
6 | def #{ali}(*args, &block)
7 | #{accessor}.__send__(:#{method}, *args, &block)
8 | end
9 | }
10 | module_eval(str, __FILE__, line_no)
11 | end
12 |
13 | end
14 |
--------------------------------------------------------------------------------
/26/my_attr.rb:
--------------------------------------------------------------------------------
1 |
2 |
3 | class Object
4 | def self.simple_attr_reader(name)
5 | code = "def #{name}; @#{name}; end"
6 | class_eval( code )
7 | end
8 | end
9 |
10 | class Object
11 | def self.simple_attr_writer(name)
12 | method_name = "#{name}="
13 | define_method( method_name ) do |value|
14 | variable_name = "@#{name}"
15 | instance_variable_set( variable_name, value )
16 | end
17 | end
18 | end
19 |
20 | class Example
21 | simple_attr_reader :color
22 | simple_attr_writer :color
23 |
24 | def initialize( color )
25 | @color = color
26 | end
27 | end
28 |
29 | e = Example.new( 'green' )
30 | puts e.color
31 | e.color = 'red'
32 | puts e.color
33 |
--------------------------------------------------------------------------------
/26/structured_doc_def_method.rb:
--------------------------------------------------------------------------------
1 | require 'structured_document'
2 | require 'pp'
3 |
4 |
5 | class StructuredDocument ##(main
6 | def self.paragraph_type( paragraph_name, options )
7 | name = options[:font_name] || :arial
8 | size = options[:font_size] || 12
9 | emphasis = options[:font_emphasis] || :none
10 |
11 | define_method(paragraph_name) do |text|
12 | paragraph = Paragraph.new( name, size, emphasis, text )
13 | self << paragraph
14 | end
15 | end
16 |
17 | # ...
18 | end ##main)
19 |
--------------------------------------------------------------------------------
/26/structured_doc_eval.rb:
--------------------------------------------------------------------------------
1 | require 'structured_document'
2 | require 'pp'
3 |
4 | class StructuredDocument ##(main
5 | def self.paragraph_type( paragraph_name, options )
6 |
7 | name = options[:font_name] || :arial
8 | size = options[:font_size] || 12
9 | emphasis = options[:font_emphasis] || :normal
10 |
11 | code = %Q{
12 | def #{paragraph_name}(text)
13 | p = Paragraph.new(:#{name}, #{size}, :#{emphasis}, text)
14 | self << p
15 | end
16 | }
17 | class_eval( code )
18 | end
19 |
20 | # ...
21 | end ##main)
22 |
--------------------------------------------------------------------------------
/27/Rakefile:
--------------------------------------------------------------------------------
1 | require '../utils/tasks.rb'
2 |
--------------------------------------------------------------------------------
/27/Rakefile.example:
--------------------------------------------------------------------------------
1 | ##(main
2 | task :default => [ :install_program , :install_data ] ##+default
3 |
4 | task :install_data => :installation_dir do
5 | cp 'fonts.dat', 'installation'
6 | end
7 |
8 | task :install_program => [ :installation_dir ] do
9 | cp 'document.rb', 'installation'
10 | end
11 |
12 | task :installation_dir do
13 | mkdir_p 'installation'
14 | end ##main)
15 |
16 |
--------------------------------------------------------------------------------
/27/broken.ripper:
--------------------------------------------------------------------------------
1 | # Error: Note the missing do on the first line...
2 |
3 | on_path( '/document/author' ) |author|
4 | author.text = 'Tolkien'
5 | end
6 |
7 | after { |doc| puts doc }
8 |
--------------------------------------------------------------------------------
/27/ex_1_author.rb:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 |
3 | require "rexml/document"
4 |
5 | File.open( 'fellowship.xml' ) do |f|
6 | doc = REXML::Document.new(f)
7 | author = REXML::XPath.first(doc, '/document/author')
8 | puts author.text
9 | end
10 |
--------------------------------------------------------------------------------
/27/ex_1_fix.rb:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 |
3 | require "rexml/document"
4 |
5 | File.open( 'fellowship.xml' ) do |f|
6 | doc = REXML::Document.new(f)
7 | REXML::XPath.each(doc, '/document/author') do |author|
8 | author.text = 'J.R.R. Tolkien'
9 | end
10 | puts doc
11 | end
12 |
13 |
--------------------------------------------------------------------------------
/27/ex_1_simple_spec.rb:
--------------------------------------------------------------------------------
1 | require '../utils/rspec_utils'
2 |
3 | describe "simple script examples" do
4 |
5 | it 'author example should work' do
6 | out = `ruby ex_1_author.rb`
7 | out.should == "J. R. R. Tolken\n"
8 | end
9 |
10 |
11 | it 'title example should work' do
12 | out = `ruby ex_1_title.rb`
13 | out.should == "A Long Expected Party\nA Shadow Of The Past\n"
14 | end
15 |
16 | it 'fix misspelling example should work' do
17 | out = `ruby ex_1_fix.rb`
18 | out.should match( /author>J.R.R. Tolkien/ )
19 | end
20 | end
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/27/ex_1_title.rb:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 |
3 | require "rexml/document"
4 |
5 | File.open( 'fellowship.xml' ) do |f|
6 | doc = REXML::Document.new(f)
7 | REXML::XPath.each(doc, '/document/chapter/title') do |title|
8 | puts title.text
9 | end
10 | end
11 |
--------------------------------------------------------------------------------
/27/fellowship.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | The Fellowship Of The Ring
5 | J. R. R. Tolken
6 | 1954
7 |
8 |
9 | A Long Expected Party
10 | When Mr. Bilbo Bagins of Bag End...
11 |
12 |
13 |
14 | A Shadow Of The Past
15 | The talk did not die down...
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/27/fix_author.ripper:
--------------------------------------------------------------------------------
1 | on_path( '/document/author' ) do |author|
2 | author.text = 'J.R.R. Tolkien'
3 | end
4 | after { |doc| puts doc }
5 |
--------------------------------------------------------------------------------
/27/fix_author_comments.ripper:
--------------------------------------------------------------------------------
1 | # Correct a common mistake
2 |
3 | on_path( '/document/author' ) do |author|
4 | author.text = 'J.R.R. Tolkien'
5 | end
6 |
7 | # Print out the whole document when done
8 |
9 | after { |doc| puts doc }
10 |
--------------------------------------------------------------------------------
/27/migration_example.rb:
--------------------------------------------------------------------------------
1 | class AddBooks < ActiveRecord::Migration
2 | def self.up
3 | create_table :books do |t|
4 | t.string :title
5 | t.integer :publisher_id
6 | end
7 | end
8 |
9 | def self.down
10 | drop_table :books
11 | end
12 | end
13 |
14 |
--------------------------------------------------------------------------------
/27/on_doc_author.ripper:
--------------------------------------------------------------------------------
1 | on_document_author { |author| puts author.text }
2 |
--------------------------------------------------------------------------------
/27/ripper1.rb:
--------------------------------------------------------------------------------
1 | require "rexml/document"
2 |
3 | class XmlRipper
4 | def initialize(&block)
5 | @before_action = proc {}
6 | @path_actions = {}
7 | @after_action = proc {}
8 | block.call( self ) if block
9 | end
10 |
11 | def on_path( path, &block )
12 | @path_actions[path] = block
13 | end
14 |
15 | def before( &block )
16 | before_action = block
17 | end
18 |
19 | def after( &block )
20 | @after_action = block
21 | end
22 |
23 | def run( xml_file_path )
24 | File.open( xml_file_path ) do |f|
25 | document = REXML::Document.new(f)
26 | @before_action.call( document )
27 | run_path_actions( document )
28 | @after_action.call( document )
29 | end
30 | end
31 |
32 | def run_path_actions( document )
33 | @path_actions.each do |path, block|
34 | REXML::XPath.each(document, path) do |element|
35 | block.call( element )
36 | end
37 | end
38 | end
39 | end
40 |
--------------------------------------------------------------------------------
/27/ripper1_fix_author.rb:
--------------------------------------------------------------------------------
1 | require 'ripper1'
2 |
3 | ripper = XmlRipper.new do |r| ##(main
4 | r.on_path( '/document/author' ) do |author|
5 | author.text = 'J.R.R. Tolkien'
6 | end
7 | r.after { |doc| puts doc }
8 | end
9 |
10 | ripper.run( 'fellowship.xml' ) ##main)
11 |
--------------------------------------------------------------------------------
/27/ripper1_spec.rb:
--------------------------------------------------------------------------------
1 | require '../utils/rspec_utils'
2 |
3 | describe "first ripper scripts" do
4 |
5 | it 'author example should work' do
6 | out = `ruby -I . ripper1_title_author.rb`
7 | out.should == "J. R. R. Tolken\nA Long Expected Party\nA Shadow Of The Past\n"
8 | end
9 |
10 |
11 | it 'fix misspelling example should work' do
12 | out = `ruby -I . ripper1_fix_author.rb`
13 | out.should match( /author>J.R.R. Tolkien/ )
14 | end
15 | end
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/27/ripper1_title_author.rb:
--------------------------------------------------------------------------------
1 | require 'ripper1'
2 |
3 | ripper = XmlRipper.new do |r| ##(main
4 | r.on_path( '/document/author' ) { |a| puts a.text } ##+doc_author
5 | r.on_path( '/document/chapter/title' ) { |t| puts t.text }
6 | end
7 |
8 | ripper.run( 'fellowship.xml' ) ##main)
9 |
--------------------------------------------------------------------------------
/27/ripper2.rb:
--------------------------------------------------------------------------------
1 | require "ripper1"
2 |
3 | class XmlRipper ##(main
4 |
5 | def initialize(&block)
6 | @before_action = proc {}
7 | @path_actions = {}
8 | @after_action = proc {}
9 | instance_eval( &block ) if block
10 | end
11 |
12 | # Rest of the class omitted...
13 |
14 | end ##main)
15 |
16 |
--------------------------------------------------------------------------------
/27/ripper2_demo.rb:
--------------------------------------------------------------------------------
1 | require 'ripper2'
2 |
3 | ripper = XmlRipper.new do ##(main
4 | on_path( '/document/author' ) do |author|
5 | author.text = 'J.R.R. Tolkien'
6 | end
7 | after { |doc| puts doc }
8 | end
9 |
10 | ripper.run( 'fellowship.xml' ) ##main)
11 |
--------------------------------------------------------------------------------
/27/ripper2_spec.rb:
--------------------------------------------------------------------------------
1 | require '../utils/rspec_utils'
2 |
3 | describe "second ripper scripts" do
4 |
5 | it 'fix title example should work' do
6 | out = `ruby -I . ripper2_demo.rb`
7 | out.should match( /author>J.R.R. Tolkien/ )
8 | end
9 |
10 | end
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/27/ripper3.rb:
--------------------------------------------------------------------------------
1 | require "ripper2"
2 |
3 | class XmlRipper ##(main
4 |
5 | def initialize_from_file( path )
6 | instance_eval( File.read( path ) )
7 | end
8 |
9 | # Rest of the class omitted...
10 |
11 | end ##main)
12 |
13 |
--------------------------------------------------------------------------------
/27/ripper3_demo.rb:
--------------------------------------------------------------------------------
1 | require "ripper3"
2 |
3 | ripper = XmlRipper.new ##(main
4 | ripper.initialize_from_file( 'fix_author.ripper' )
5 | ripper.run( 'fellowship.xml') ##main)
6 |
--------------------------------------------------------------------------------
/27/ripper3_spec.rb:
--------------------------------------------------------------------------------
1 | require '../utils/rspec_utils'
2 |
3 | describe "second ripper scripts" do
4 |
5 | it 'fix title example should work' do
6 | out = `ruby -I . ripper3_demo.rb`
7 | out.should match( /author>J.R.R. Tolkien/ )
8 | end
9 |
10 | end
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/27/ripper4.rb:
--------------------------------------------------------------------------------
1 | require "ripper3"
2 |
3 | class XmlRipper ##(main
4 |
5 | # Rest of the class omitted...
6 |
7 | def method_missing( name, *args, &block )
8 | return super unless name.to_s =~ /on_.*/
9 | parts = name.to_s.split( "_" )
10 | parts.shift
11 | xpath = parts.join( '/' )
12 | on_path( xpath, &block )
13 | end
14 | end ##main)
15 |
--------------------------------------------------------------------------------
/27/ripper4_main.rb:
--------------------------------------------------------------------------------
1 | require "ripper4"
2 |
3 | r = XmlRipper.new ##(main
4 | r.initialize_from_file( ARGV[0] )
5 | r.run( ARGV[1] ) ##main)
6 |
--------------------------------------------------------------------------------
/27/ripper4_spec.rb:
--------------------------------------------------------------------------------
1 |
2 | describe 'xmlripper4' do
3 |
4 | it 'should work with the commented version' do
5 | out = `ruby -I . ripper4_main.rb on_doc_author.ripper fellowship.xml`
6 | out.should == "J. R. R. Tolken\n"
7 | end
8 | end
9 |
--------------------------------------------------------------------------------
/27/ripper5.rb:
--------------------------------------------------------------------------------
1 | require "ripper2"
2 |
3 | class XmlRipper ##(main
4 |
5 | def initialize_from_file( path )
6 | instance_eval( File.read( path ), path )
7 | end
8 |
9 | # Rest of the class omitted...
10 |
11 | end ##main)
12 |
13 |
--------------------------------------------------------------------------------
/27/ripper5_main.rb:
--------------------------------------------------------------------------------
1 | require "ripper5"
2 |
3 | r = XmlRipper.new
4 | r.initialize_from_file( ARGV[0] )
5 | r.run( ARGV[1] )
6 |
--------------------------------------------------------------------------------
/28/Rakefile:
--------------------------------------------------------------------------------
1 |
2 | Targets = %w{ fellowship.xml spec out.odt}
3 |
4 | require '../utils/tasks.rb'
5 |
6 | CLEAN.include('fellowship.xml')
7 |
8 |
9 | file 'fellowship.xml' do |f|
10 | cp '../27/fellowship.xml', '.'
11 | end
12 |
13 | task :init => 'fellowship.xml'
14 |
--------------------------------------------------------------------------------
/28/bad_delete.ezr:
--------------------------------------------------------------------------------
1 |
2 | delete
3 |
4 |
--------------------------------------------------------------------------------
/28/bad_examples.rb:
--------------------------------------------------------------------------------
1 | require '../utils/rspec_utils'
2 |
3 | shared_examples_for "it has decent error handling" do
4 | it 'should blow up on a bad print' do
5 | out = error_message_of { EzRipper.new( 'bad_print.ezr' ).run( 'fellowship.xml' ) }
6 | out.should match( /Expected print / )
7 | end
8 |
9 | it 'should blow up on a bad delete' do
10 | out = error_message_of { EzRipper.new( 'bad_delete.ezr' ).run( 'fellowship.xml' ) }
11 | out.should match( /Expected delete / )
12 | end
13 |
14 | it 'should blow up on a bad replace' do
15 | out = error_message_of { EzRipper.new( 'bad_replace.ezr' ).run( 'fellowship.xml' ) }
16 | out.should match( /Expected replace / )
17 | end
18 |
19 | it 'should blow up on a bad delete' do
20 | out = error_message_of { EzRipper.new( 'bad_print_document.ezr' ).run( 'fellowship.xml' ) }
21 | out.should match( /Expected print_document/ )
22 | end
23 | end
24 |
--------------------------------------------------------------------------------
/28/bad_print.ezr:
--------------------------------------------------------------------------------
1 | print
2 |
3 |
--------------------------------------------------------------------------------
/28/bad_print_document.ezr:
--------------------------------------------------------------------------------
1 | print_document aa bb cc dd
2 |
3 |
--------------------------------------------------------------------------------
/28/bad_replace.ezr:
--------------------------------------------------------------------------------
1 | replace /document/author
2 |
3 |
--------------------------------------------------------------------------------
/28/bad_statement.ezr:
--------------------------------------------------------------------------------
1 | foobar /document/author
2 |
3 |
--------------------------------------------------------------------------------
/28/bad_upcase.ezr:
--------------------------------------------------------------------------------
1 | uppercase
2 | print_document
3 |
--------------------------------------------------------------------------------
/28/comments.ezr:
--------------------------------------------------------------------------------
1 | # Lead comment
2 |
3 | uppercase document/author
4 | print_document
5 |
6 | # comment at the end
7 |
--------------------------------------------------------------------------------
/28/common.rb:
--------------------------------------------------------------------------------
1 | require 'fileutils'
2 | require '../utils/rspec_utils'
3 |
4 | dir = File.dirname( __FILE__ )
5 | $: << "#{dir}/../27"
6 |
7 |
--------------------------------------------------------------------------------
/28/edit.ezr:
--------------------------------------------------------------------------------
1 | delete /document/published
2 | replace /document/author Tolkien
3 | print_document
4 |
--------------------------------------------------------------------------------
/28/ex_1_spec.rb:
--------------------------------------------------------------------------------
1 | require 'common'
2 | require 'ripper4.rb'
3 | require 'ez_ripper1'
4 |
5 | require 'good_examples'
6 |
7 | describe EzRipper do
8 | it_should_behave_like "it handles correct ezr programs"
9 | end
10 |
11 |
12 |
--------------------------------------------------------------------------------
/28/ex_2_spec.rb:
--------------------------------------------------------------------------------
1 | require 'common'
2 | require 'ez_ripper2.rb'
3 | require 'bad_examples'
4 | require 'good_examples'
5 |
6 | describe EzRipper do
7 | it_should_behave_like "it handles correct ezr programs"
8 | it_should_behave_like "it has decent error handling"
9 | end
10 |
11 |
--------------------------------------------------------------------------------
/28/ex_3_spec.rb:
--------------------------------------------------------------------------------
1 | require 'common'
2 | require 'ez_ripper3.rb'
3 | require 'bad_examples'
4 | require 'good_examples'
5 |
6 | describe EzRipper do
7 | it 'should handle uppercase command' do
8 | EzRipper.new( 'upcase.ezr').run('fellowship.xml' )
9 | out = output_of { EzRipper.new( 'upcase.ezr').run('fellowship.xml' ) }
10 | out.should match( /FELLOWSHIP/ )
11 | end
12 |
13 | it 'should handle a bad upcase command' do
14 | out = error_message_of { EzRipper.new( 'bad_upcase.ezr').run('fellowship.xml' ) }
15 | out.should match( /Expected uppercase / )
16 | end
17 |
18 | end
19 |
20 |
--------------------------------------------------------------------------------
/28/ex_4_spec.rb:
--------------------------------------------------------------------------------
1 | require 'common'
2 | require 'ez_ripper4.rb'
3 |
4 | describe EzRipper do
5 | it 'should handle comments' do
6 | out = output_of { EzRipper.new( 'comments.ezr').run('fellowship.xml' ) }
7 | out.should match( /TOL/ )
8 | end
9 | end
10 |
11 |
--------------------------------------------------------------------------------
/28/ex_6_spec.rb:
--------------------------------------------------------------------------------
1 | require 'common'
2 | require 'ez_ripper6'
3 |
4 |
5 | describe 'EzRipper with execute command' do
6 | it 'should work as described in the book' do
7 | ezr = EzRipper.new( 'execute.ezr' )
8 | output_of { ezr.run( 'fellowship.xml' ) }.should match( /author is.*Tol/m )
9 | end
10 | end
11 |
12 |
--------------------------------------------------------------------------------
/28/ex_erb_spec.rb:
--------------------------------------------------------------------------------
1 | require 'erb'
2 | require '../utils/rspec_utils'
3 |
4 | describe 'converting erb' do
5 | it 'should work as described in book' do
6 | template = File.read('example.erb')
7 | erb = ERB.new( template )
8 | out = erb.result
9 | out.should match( /Today is/ )
10 | File.write( 'example.erb.out', out )
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/28/ex_haml_spec.rb:
--------------------------------------------------------------------------------
1 | require 'haml'
2 | require '../utils/rspec_utils'
3 |
4 | describe 'converting haml' do
5 | it 'should work as described in book' do
6 | template = File.read('example.haml')
7 | haml_engine = Haml::Engine.new(template)
8 | out = haml_engine.render
9 | out.should match( /.*<\/html>/m )
10 | out.should match( /.*<\/body>/m )
11 | out.should match( /Today is/m )
12 | File.write( 'example.html', out )
13 | end
14 | end
15 |
--------------------------------------------------------------------------------
/28/example.erb:
--------------------------------------------------------------------------------
1 | Today is <%= Time.new %>
2 |
--------------------------------------------------------------------------------
/28/example.haml:
--------------------------------------------------------------------------------
1 | %html
2 | %body
3 | #main
4 | Today is
5 | = Time.new
6 |
--------------------------------------------------------------------------------
/28/execute.ezr:
--------------------------------------------------------------------------------
1 | execute '/document/author' 'puts "the author is #{el.text}"'
2 |
--------------------------------------------------------------------------------
/28/ez_ripper1_demo.rb:
--------------------------------------------------------------------------------
1 | require 'ez_ripper1.rb'
2 |
3 |
4 | ezr = EzRipper.new( 'author.ezr' )
5 | puts "running"
6 | ezr.run( 'fellowship.xml' )
7 |
8 |
--------------------------------------------------------------------------------
/28/ez_ripper2_demo.rb:
--------------------------------------------------------------------------------
1 | require 'ez_ripper2.rb'
2 |
3 |
4 | ezr = EzRipper.new( 'author.ezr' )
5 | puts "running"
6 | ezr.run( 'fellowship.xml' )
7 |
8 |
--------------------------------------------------------------------------------
/28/ez_ripper3.rb:
--------------------------------------------------------------------------------
1 | require 'ez_ripper2'
2 |
3 | class EzRipper
4 |
5 | # Most of the class omitted...
6 |
7 | def parse_statement( statement )
8 | tokens = statement.strip.split
9 | return if tokens.empty?
10 |
11 | case tokens.first
12 |
13 | when 'uppercase' ##(uppercase
14 | raise "Expected uppercase " unless tokens.size == 2
15 | @ripper.on_path( tokens[1] ) { |el| el.text = el.text.upcase } ##uppercase)
16 |
17 | when 'print_document'
18 | raise "print_document does not take any arguments" unless tokens.size == 1
19 | @ripper.after do |doc|
20 | puts doc
21 | end
22 |
23 | else
24 | raise "Unknown keyword: #{tokens.first}"
25 | end
26 | end
27 | end
28 |
--------------------------------------------------------------------------------
/28/ez_ripper3_demo.rb:
--------------------------------------------------------------------------------
1 | require 'ez_ripper3'
2 |
3 |
4 | ezr = EzRipper.new( 'upcase.ezr' )
5 | ezr.run( 'fellowship.xml' )
6 |
7 |
--------------------------------------------------------------------------------
/28/ez_ripper4.rb:
--------------------------------------------------------------------------------
1 | require 'ez_ripper2'
2 |
3 | class EzRipper
4 |
5 | # Most of the class omitted...
6 |
7 | def parse_statement( statement ) ##(comment
8 | statement = statement.sub( /#.*/, '' )
9 | tokens = statement.strip.split
10 | return if tokens.empty? ##comment)
11 |
12 | case tokens.first
13 |
14 | when 'uppercase' ##(uppercase
15 | raise "Expected uppercase " unless tokens.size == 2
16 | @ripper.on_path( tokens[1] ) { |el| el.text = el.text.upcase } ##uppercase)
17 |
18 | when 'print_document'
19 | raise "print_document does not take any arguments" unless tokens.size == 1
20 | @ripper.after do |doc|
21 | puts doc
22 | end
23 |
24 | else
25 | raise "Unknown keyword: #{tokens.first}"
26 | end
27 | end
28 | end
29 |
--------------------------------------------------------------------------------
/28/ez_ripper4_demo.rb:
--------------------------------------------------------------------------------
1 | require 'ez_ripper4'
2 |
3 |
4 | ezr = EzRipper.new( 'all.ezr' )
5 | puts "running"
6 | ezr.run( 'fellowship.xml' )
7 |
8 |
--------------------------------------------------------------------------------
/28/ez_ripper5.rb:
--------------------------------------------------------------------------------
1 | require 'ez_ripper2'
2 |
3 | class EzRipper
4 |
5 | # Most of the class omitted...
6 |
7 | def parse_statement( statement ) ##(main
8 |
9 | statement = statement.sub( /#.*/, '' )
10 |
11 | case statement.strip
12 | when ''
13 | # Skip blank lines
14 |
15 | when /print\s+'(.*?)'/
16 | @ripper.on_path( $1 ) do |el|
17 | puts el.text
18 | end
19 |
20 | when /delete\s+'(.*?)'/
21 | @ripper.on_path( $1 ) { |el| el.remove }
22 |
23 | when /replace\s+'(.*?)'\s+'(.*?)'$/
24 | @ripper.on_path( $1 ) { |el| el.text = $2 }
25 |
26 | when /uppercase\s+'(.*?)'/
27 | @ripper.on_path( $1 ) { |el| el.text = el.text.upcase }
28 |
29 | when /print_document/
30 | @ripper.after do |doc|
31 | puts doc
32 | end
33 |
34 | else
35 | raise "Don't know what to do with: #{statement}"
36 | end
37 | end ##main)
38 | end
39 |
40 |
--------------------------------------------------------------------------------
/28/ez_ripper5_demo.rb:
--------------------------------------------------------------------------------
1 | require 'ez_ripper4'
2 |
3 |
4 | ezr = EzRipper.new( 'all.ezr' )
5 | puts "running"
6 | ezr.run( 'fellowship.xml' )
7 |
8 |
--------------------------------------------------------------------------------
/28/ez_ripper6.rb:
--------------------------------------------------------------------------------
1 | ##
2 | require 'ez_ripper2'
3 |
4 | class EzRipper
5 |
6 | # Most of the class omitted...
7 |
8 | def parse_statement( statement )
9 | case statement.strip
10 | when ''
11 | # Skip blank lines
12 |
13 | when /^\W*#/
14 | # Skip comments
15 |
16 | when /execute\s+'(.*?)'\s+'(.*?)'$/ ##(main
17 | @ripper.on_path( $1 ) { |el| eval( $2 ) } ##main)
18 |
19 | when /print\s+'(.*?)'/
20 | @ripper.on_path( $1 ) do |el|
21 | puts el.text
22 | end
23 |
24 | when /delete\s+'(.*?)'/
25 | @ripper.on_path( $1 ) { |el| el.remove }
26 |
27 | when /replace\s+'(.*?)'\s+'(.*?)'$/
28 | @ripper.on_path( $1 ) { |el| el.text = $2 }
29 |
30 | when /uppercase\s+'(.*?)'/
31 | @ripper.on_path( $1 ) { |el| el.text = el.text.upcase }
32 |
33 | when /print_document/
34 | @ripper.after do |doc|
35 | puts doc
36 | end
37 |
38 | else
39 | raise "Don't know what to do with: #{statement}"
40 | end
41 | end
42 | end
43 |
44 |
--------------------------------------------------------------------------------
/28/ez_ripper_statement.tt:
--------------------------------------------------------------------------------
1 | grammar EzRipperStatement
2 |
3 | rule statement
4 | comment/delete_statement/replace_statement/print_statement
5 | end
6 |
7 | rule comment
8 | "#" .*
9 | end
10 |
11 | rule delete_statement
12 | "delete" sp quoted_argument sp
13 | end
14 |
15 | rule replace_statement
16 | "replace" sp quoted_argument sp quoted_argument sp
17 | end
18 |
19 | rule print_statement
20 | "filter" sp quoted_argument sp
21 | end
22 |
23 | rule quoted_argument
24 | "'" argument "'"
25 | end
26 |
27 | rule argument
28 | (!"'" . )*
29 | end
30 |
31 | rule sp
32 | [ \t\n]*
33 | end
34 |
35 | end
36 |
--------------------------------------------------------------------------------
/28/ez_ripper_statement_spec.rb:
--------------------------------------------------------------------------------
1 | require 'pp'
2 |
3 | describe 'EzRipperStatementParser' do
4 |
5 | it 'should work as advertised' do
6 | require 'treetop' ##(main
7 | require 'ez_ripper_statement'
8 |
9 | statement = "replace '/document/author' 'Russ Olsen'"
10 | parser = EzRipperStatementParser.new
11 | parse_tree = parser.parse( statement ) ##main)
12 |
13 | parse_tree.should_not == nil
14 | end
15 | end
16 |
--------------------------------------------------------------------------------
/28/ezr.rb:
--------------------------------------------------------------------------------
1 | require 'ezripper1.rb'
2 |
3 |
4 | ezr = EZRipper.new( ARGV[0] )
5 | ezr.run( ARGV[1] )
6 |
7 |
--------------------------------------------------------------------------------
/28/good_examples.rb:
--------------------------------------------------------------------------------
1 | require '../utils/rspec_utils'
2 |
3 | shared_examples_for "it handles correct ezr programs" do
4 | it 'print author example should work' do
5 | out = output_of { EzRipper.new( 'print_author.ezr').run('fellowship.xml' ) }
6 | out.should match( /Tol/ )
7 | end
8 |
9 | it 'replace delete example should work' do
10 | FileUtils.cp 'replace_delete.ezr', 'temp.ezr'
11 | File.open( 'temp.ezr', 'a' ) {|f| f.puts 'print_document' }
12 |
13 | out = output_of { EzRipper.new('temp.ezr').run('fellowship.xml') }
14 | out.should match( /Tolkien/m )
15 | end
16 |
17 | it 'replace delete print example should work' do
18 | out = output_of {
19 | EzRipper.new( 'edit.ezr').run('fellowship.xml' ) ##+edit_ezr
20 | }
21 | out.should match( /Tol/ )
22 | out.should_not match( /published/ )
23 | end
24 | end
25 |
--------------------------------------------------------------------------------
/28/print_author.ezr:
--------------------------------------------------------------------------------
1 | print /document/author
2 |
--------------------------------------------------------------------------------
/28/replace_delete.ezr:
--------------------------------------------------------------------------------
1 | delete /document/published
2 | replace /document/author Tolkien
3 |
--------------------------------------------------------------------------------
/28/temp.ezr:
--------------------------------------------------------------------------------
1 | delete /document/published
2 | replace /document/author Tolkien
3 | print_document
4 |
--------------------------------------------------------------------------------
/28/upcase.ezr:
--------------------------------------------------------------------------------
1 | uppercase /document/title
2 | print_document
3 |
--------------------------------------------------------------------------------
/29/BachGavotteShort.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/russolsen/eloquent_ruby_code/a7e2a638ef9920a6f71d53529ac7801b6b594b93/29/BachGavotteShort.mp3
--------------------------------------------------------------------------------
/29/README.md:
--------------------------------------------------------------------------------
1 | The info in this directory is mostly outdated.
2 |
--------------------------------------------------------------------------------
/29/Rakefile:
--------------------------------------------------------------------------------
1 |
2 | task :default do
3 | puts "The code in this directory is mostly outdated"
4 | end
5 |
6 | task :clean do
7 | puts "This is as clean as it gets"
8 | end
9 |
--------------------------------------------------------------------------------
/29/document_simple/Rakefile:
--------------------------------------------------------------------------------
1 | require 'spec/rake/spectask'
2 | require 'rake/gempackagetask'
3 |
4 | task :default => [ :spec, :gem ]
5 |
6 | Spec::Rake::SpecTask.new do |t|
7 | t.spec_files = FileList['spec/**/*_spec.rb']
8 | end
9 |
10 | gem_spec = Gem::Specification.new do |s|
11 | s.name = "document"
12 | s.version = "1.0.1"
13 | s.authors = ["Russ Olsen"]
14 | s.date = %q{2010-01-01}
15 | s.description = 'Document - Simple document class'
16 | s.summary = s.description
17 | s.email = 'russ@russolsen.com'
18 | s.files = [ 'README', 'lib/document.rb', 'spec/document_spec.rb' ]
19 | s.homepage = 'http://www.russolsen.com'
20 | s.has_rdoc = true
21 | s.rubyforge_project = 'simple_document'
22 | end
23 |
24 | Rake::GemPackageTask.new( gem_spec ) do |t|
25 | t.need_zip = true
26 | end
27 |
28 | task :push => :gem do |t|
29 | sh "gem push pkg/#{gem_spec.name}-#{gem_spec.version}.gem"
30 | end
31 |
--------------------------------------------------------------------------------
/29/document_simple/document.gemspec:
--------------------------------------------------------------------------------
1 | Gem::Specification.new do |s|
2 | s.name = "document"
3 | s.version = "1.0.1"
4 | s.authors = ["Russ Olsen"]
5 | s.date = %q{2010-01-01}
6 | s.description = 'Document - Simple document class'
7 | s.summary = s.description
8 | s.email = 'russ@russolsen.com'
9 | s.files = ['README', 'lib/document.rb','spec/document_spec.rb']
10 | s.homepage = 'http://www.russolsen.com'
11 | s.has_rdoc = true
12 | s.rubyforge_project = 'simple_document'
13 | end
14 |
--------------------------------------------------------------------------------
/29/document_simple/foo.rb:
--------------------------------------------------------------------------------
1 | puts File.realname(File.dirname(__FILE__))
2 |
--------------------------------------------------------------------------------
/29/document_simple/hoe.rb:
--------------------------------------------------------------------------------
1 | puts "local hoe executed"
2 |
--------------------------------------------------------------------------------
/29/document_simple/lib/document.rb:
--------------------------------------------------------------------------------
1 |
2 |
3 | class Document
4 |
5 | attr_accessor :title, :author, :content
6 |
7 | def initialize( title, author, content )
8 | @title = title
9 | @author = author
10 | @content = content
11 | end
12 |
13 | def words
14 | @content.split
15 | end
16 |
17 | def word_count
18 | words.size
19 | end
20 |
21 | def average_word_length
22 | number_word_characters / word_count
23 | end
24 |
25 | def number_word_characters
26 | words.inject( 0 ) { |total, word| total += word.size }
27 | end
28 |
29 | end
30 |
--------------------------------------------------------------------------------
/29/document_simple/load_twice.rb:
--------------------------------------------------------------------------------
1 |
2 | require 'hoe'
3 | dir = File.expand_path( File.dirname(__FILE__) )
4 | require File.join( dir, 'hoe' )
5 |
--------------------------------------------------------------------------------
/29/document_simple/pkg/document-1.0.1.gem:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/russolsen/eloquent_ruby_code/a7e2a638ef9920a6f71d53529ac7801b6b594b93/29/document_simple/pkg/document-1.0.1.gem
--------------------------------------------------------------------------------
/29/document_simple/spec/document_spec.rb:
--------------------------------------------------------------------------------
1 | $: << "#{File.dirname(__FILE__)}/../lib"
2 |
3 | require 'document'
4 |
5 | describe Document do
6 |
7 | before :each do
8 | @document = Document.new( 'test', 'russ', 'nothing' )
9 | end
10 |
11 | it "should hold onto the title, author and content" do
12 | @document.title.should == 'test'
13 | @document.author.should == 'russ'
14 | @document.content.should == 'nothing'
15 | end
16 |
17 | it "should be able to split content into words" do
18 | @document.content = 'the rain in spain'
19 | @document.words.should == %w{ the rain in spain }
20 | end
21 | end
22 |
--------------------------------------------------------------------------------
/29/ex_1_mp3info_spec.rb:
--------------------------------------------------------------------------------
1 | describe 'Mp3Info' do
2 |
3 | it 'should work like the book says' do
4 | require 'mp3info' ##(main
5 |
6 | Mp3Info.open( 'BachGavotteShort.mp3' ) do |info|
7 | puts "title: #{info.tag.title}"
8 | puts "artist: #{info.tag.artist}"
9 | puts "album: #{info.tag.album}"
10 | end ##main)
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/29/ex_2_gem_cmds_spec.rb:
--------------------------------------------------------------------------------
1 | require '../utils/rspec_utils'
2 |
3 | describe 'gem command' do
4 |
5 | it 'should have an install cmd' do
6 | eval "`#{File.read('gem.install.cmd')}`"
7 | end
8 |
9 | it 'should install a specific gem version' do
10 | eval "`#{File.read('gem.install.04.cmd')}`"
11 | end
12 |
13 | it 'should install many gem version' do
14 | eval "`#{File.read('gem.install.many.cmd')}`"
15 | end
16 |
17 | it 'should have a list subcomment' do
18 | out = eval("`#{File.read('gem.list.cmd')}`")
19 | out.should match(/6\.12.*6\.9.*0\.4/m)
20 | File.write( 'versions.txt', out.breakup )
21 | end
22 |
23 | end
24 |
--------------------------------------------------------------------------------
/29/ex_2_specific_version_spec.rb:
--------------------------------------------------------------------------------
1 |
2 | describe 'getting a specific version of a gem' do
3 |
4 | it 'should work like the books says' do
5 | gem 'ruby-mp3info', '=0.5'
6 | require 'mp3info'
7 | end
8 |
9 | end
10 |
--------------------------------------------------------------------------------
/29/file_test.rb:
--------------------------------------------------------------------------------
1 | p __FILE__
2 |
--------------------------------------------------------------------------------
/29/gem.install.04.cmd:
--------------------------------------------------------------------------------
1 | gem install --version 0.4 ruby-mp3info
2 |
--------------------------------------------------------------------------------
/29/gem.install.cmd:
--------------------------------------------------------------------------------
1 | gem install ruby-mp3info
2 |
--------------------------------------------------------------------------------
/29/gem.install.many.cmd:
--------------------------------------------------------------------------------
1 | gem install --version 0.5 ruby-mp3info
2 | gem install --version 0.5.1 ruby-mp3info
3 | gem install --version 0.6 ruby-mp3info
4 |
--------------------------------------------------------------------------------
/29/gem.list.cmd:
--------------------------------------------------------------------------------
1 | gem list -a --remote ruby-mp3info
2 |
--------------------------------------------------------------------------------
/29/versions.txt:
--------------------------------------------------------------------------------
1 | ruby-mp3info (0.8, 0.7.2, 0.7.1, 0.7, 0.6.16, 0.6.15,
2 | 0.6.14, 0.6.13, 0.6.12, 0.6.11, 0.6.10, 0.6.9, 0.6.8,
3 | 0.6.7, 0.6.6, 0.6.5, 0.6.4, 0.6.3, 0.6.2, 0.6.1, 0.6,
4 | 0.5.1, 0.5, 0.4)
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | source "https://rubygems.org"
2 |
3 | gem 'rake'
4 | gem 'rspec'
5 | gem 'xml-simple'
6 | gem 'shoulda'
7 | gem 'text'
8 | gem 'mp3info'
9 | gem 'haml'
10 | gem 'treetop'
11 | gem 'test-unit'
12 |
--------------------------------------------------------------------------------
/Rakefile:
--------------------------------------------------------------------------------
1 |
2 |
3 | Dirs = Dir['[0-9][0-9]'].sort
4 |
5 | def build_target( target )
6 | Dirs.each do |dir|
7 | sh "cd #{dir}; rake #{target}"
8 | end
9 | end
10 |
11 | task :default do
12 | build_target( :default )
13 | end
14 |
15 | task :sniff do
16 | build_target( :sniff )
17 | end
18 |
19 | task :clean do
20 | build_target( :clean )
21 | end
22 |
--------------------------------------------------------------------------------
/code/doc1.rb:
--------------------------------------------------------------------------------
1 | class Document
2 | attr_accessor :title, :author, :content
3 |
4 | def initialize(title, author, content)
5 | @title = title
6 | @author = author
7 | @content = content
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/code/doc2.rb:
--------------------------------------------------------------------------------
1 | class Document
2 | attr_accessor :title, :author, :content
3 |
4 | def initialize(title, author, content)
5 | @title = title
6 | @author = author
7 | @content = content
8 | end
9 |
10 | def words
11 | @content.split
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/code/doc3.rb:
--------------------------------------------------------------------------------
1 | class Document
2 | attr_accessor :title, :author, :content
3 |
4 | def initialize(title, author, content)
5 | @title = title
6 | @author = author
7 | @content = content
8 | end
9 |
10 | def words
11 | @content.split
12 | end
13 |
14 | def word_count
15 | words.size
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/code/doc4.rb:
--------------------------------------------------------------------------------
1 | class Document
2 | attr_accessor :title, :author, :content
3 |
4 | def initialize(title, author, content)
5 | @title = title
6 | @author = author
7 | @content = content
8 | end
9 |
10 | def words
11 | @content.split
12 | end
13 |
14 | def word_count
15 | words.size
16 | end
17 |
18 | def average_word_length
19 | all_words = words
20 |
21 | len = all_words.inject(0.0){ |total, word| word.size + total }
22 | len / all_words.size
23 | end
24 | end
25 |
--------------------------------------------------------------------------------
/code/doc_access.rb:
--------------------------------------------------------------------------------
1 | attr_accessor :title, :author, :content
2 |
--------------------------------------------------------------------------------
/code/doc_avg_word_len.rb:
--------------------------------------------------------------------------------
1 | def average_word_length
2 | len = words.inject(0.0){ |total, word| word.size + total }
3 | len / words.size
4 | end
5 |
--------------------------------------------------------------------------------
/code/doc_init.rb:
--------------------------------------------------------------------------------
1 | def initialize(title, author, content)
2 | @title = title
3 | @author = author
4 | @content = content
5 | end
6 |
--------------------------------------------------------------------------------
/code/doc_word_count.rb:
--------------------------------------------------------------------------------
1 | def word_count
2 | words.size
3 | end
4 |
--------------------------------------------------------------------------------
/code/doc_words.rb:
--------------------------------------------------------------------------------
1 | def words
2 | @content.split
3 | end
4 |
--------------------------------------------------------------------------------
/code/document.rb:
--------------------------------------------------------------------------------
1 | class Document ##(simple_doc
2 | attr_accessor :title, :author, :content
3 |
4 | def initialize(title, author, content)
5 | @title = title
6 | @author = author
7 | @content = content
8 | end
9 |
10 | def words
11 | @content.split
12 | end ##simple_doc)
13 |
14 | def average_word_length ##(avg_word_len
15 | all_words = words
16 |
17 | len = all_words.inject(0.0){ |total, word| word.size + total }
18 | len / all_words.size
19 | end ##avg_word_len)
20 | end ##+simple_doc
21 |
--------------------------------------------------------------------------------
/code/simple_doc.rb:
--------------------------------------------------------------------------------
1 | class Document
2 | attr_accessor :title, :author, :content
3 |
4 | def initialize(title, author, content)
5 | @title = title
6 | @author = author
7 | @content = content
8 | end
9 |
10 | def words
11 | @content.split
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/rvmrc.example:
--------------------------------------------------------------------------------
1 | rvm use 1.9.3-p327@er --create
2 |
--------------------------------------------------------------------------------
/utils/rspec_utils.rb:
--------------------------------------------------------------------------------
1 | require 'stringio'
2 | require 'pp'
3 |
4 | def output_of( &block )
5 | output = StringIO.new
6 | $stdout = output
7 | begin
8 | block.call
9 | ensure
10 | $stdout = STDOUT
11 | end
12 | output.string
13 | end
14 |
15 | def error_message_of( &block )
16 | begin
17 | block.call
18 | fail( "did not throw an exception" )
19 | rescue
20 | return $!.message
21 | end
22 | end
23 |
24 | class String
25 | def breakup
26 | bits = self.split
27 | result = ['']
28 | bits.each do | bit |
29 | result << '' if result.last.size > 50
30 | result.last << bit
31 | result.last << ' '
32 | end
33 | result.join("\n")
34 | end
35 | end
36 |
37 | class File
38 | def self.write( path, string )
39 | File.open( path, 'w' ) {|f| f.print(string)}
40 | end
41 | end
42 |
--------------------------------------------------------------------------------
/utils/tasks.rb:
--------------------------------------------------------------------------------
1 | require 'rake'
2 | require 'rake/clean'
3 | require 'rspec/core/rake_task'
4 | require 'pathname'
5 |
6 | desc "Run all examples"
7 | task :spec do |t|
8 | Dir['*_spec.rb'].sort.each do |f|
9 | puts "Spec'ing #{f}"
10 | sh "rspec -I . #{f}"
11 | end
12 | end
13 |
14 | task :init
15 |
16 | task :default => %w{init spec}
17 |
18 | task :irb do
19 | sh "irb -I ."
20 | end
21 |
--------------------------------------------------------------------------------