Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 111 lines (92 sloc) 2.639 kB
793d388 First commit, 32 completed koans
Jon-Paul Lussier authored
1 require File.expand_path(File.dirname(__FILE__) + '/edgecase')
2
3 class AboutSandwichCode < EdgeCase::Koan
4
5 def count_lines(file_name)
6 file = open(file_name)
7 count = 0
8 while line = file.gets
9 count += 1
10 end
11 count
12 ensure
13 file.close if file
14 end
15
16 def test_counting_lines
f690cd1 @jonpaul 200 koans done
authored
17 assert_equal 4, count_lines("example_file.txt")
793d388 First commit, 32 completed koans
Jon-Paul Lussier authored
18 end
19
20 # ------------------------------------------------------------------
21
22 def find_line(file_name)
23 file = open(file_name)
24 while line = file.gets
25 return line if line.match(/e/)
26 end
27 ensure
28 file.close if file
29 end
30
31 def test_finding_lines
f690cd1 @jonpaul 200 koans done
authored
32 assert_equal "test\n", find_line("example_file.txt")
793d388 First commit, 32 completed koans
Jon-Paul Lussier authored
33 end
34
35 # ------------------------------------------------------------------
36 # THINK ABOUT IT:
37 #
38 # The count_lines and find_line are similar, and yet different.
39 # They both follow the pattern of "sandwich code".
40 #
41 # Sandwich code is code that comes in three parts: (1) the top slice
42 # of bread, (2) the meat, and (3) the bottom slice of bread. The
43 # the bread part of the sandwich almost always goes together, but
44 # the meat part changes all the time.
45 #
46 # Because the changing part of the sandwich code is in the middle,
47 # abstracting the top and bottom bread slices to a library can be
48 # difficult in many languages.
49 #
50 # (Aside for C++ programmers: The idiom of capturing allocated
51 # pointers in a smart pointer constructor is an attempt to deal with
52 # the problem of sandwich code for resource allocation.)
53 #
54 # Consider the following code:
55 #
56
57 def file_sandwich(file_name)
58 file = open(file_name)
59 yield(file)
60 ensure
61 file.close if file
62 end
63
64 # Now we write:
65
66 def count_lines2(file_name)
67 file_sandwich(file_name) do |file|
68 count = 0
69 while line = file.gets
70 count += 1
71 end
72 count
73 end
74 end
75
76 def test_counting_lines2
f690cd1 @jonpaul 200 koans done
authored
77 assert_equal 4, count_lines2("example_file.txt")
793d388 First commit, 32 completed koans
Jon-Paul Lussier authored
78 end
79
80 # ------------------------------------------------------------------
81
82 def find_line2(file_name)
f690cd1 @jonpaul 200 koans done
authored
83 file_sandwich(file_name) do |file|
84 while line = file.gets
85 return line if line.match(/e/)
86 end
87 end
793d388 First commit, 32 completed koans
Jon-Paul Lussier authored
88 end
89
90 def test_finding_lines2
f690cd1 @jonpaul 200 koans done
authored
91 assert_equal "test\n", find_line2("example_file.txt")
793d388 First commit, 32 completed koans
Jon-Paul Lussier authored
92 end
93
94 # ------------------------------------------------------------------
95
96 def count_lines3(file_name)
97 open(file_name) do |file|
98 count = 0
99 while line = file.gets
100 count += 1
101 end
102 count
103 end
104 end
105
106 def test_open_handles_the_file_sandwich_when_given_a_block
f690cd1 @jonpaul 200 koans done
authored
107 assert_equal 4, count_lines3("example_file.txt")
793d388 First commit, 32 completed koans
Jon-Paul Lussier authored
108 end
109
110 end
Something went wrong with that request. Please try again.