1 require File.expand_path(File.dirname(__FILE__) + '/edgecase')
3 class AboutSandwichCode < EdgeCase::Koan
5 def count_lines(file_name)
16 def test_counting_lines
17 assert_equal __(4), count_lines("example_file.txt")
20 # ------------------------------------------------------------------
22 def find_line(file_name)
23 file = open(file_name)
24 while line = file.gets
25 return line if line.match(/e/)
31 def test_finding_lines
32 assert_equal __("test\n"), find_line("example_file.txt")
35 # ------------------------------------------------------------------
38 # The count_lines and find_line are similar, and yet different.
39 # They both follow the pattern of "sandwich code".
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.
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.
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.)
54 # Consider the following code:
57 def file_sandwich(file_name)
58 file = open(file_name)
66 def count_lines2(file_name)
67 file_sandwich(file_name) do |file|
69 while line = file.gets
76 def test_counting_lines2
77 assert_equal __(4), count_lines2("example_file.txt")
80 # ------------------------------------------------------------------
82 def find_line2(file_name)
83 # Rewrite find_line using the file_sandwich library function.
85 file_sandwich(file_name) do |file|
87 return line if line =~ /e/
93 def test_finding_lines2
94 assert_equal __("test\n"), find_line2("example_file.txt")
97 # ------------------------------------------------------------------
99 def count_lines3(file_name)
100 open(file_name) do |file|
102 while line = file.gets
109 def test_open_handles_the_file_sandwich_when_given_a_block
110 assert_equal __(4), count_lines3("example_file.txt")