From: Roelof Wobben Date: 2012-09-24T16:17:04+09:00 Subject: sandwhich principle (ruby koans) --_ddbee70d-be91-475d-bb58-2cddf8125973_ Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable hello=2C I'm working on ruby koans. Now I have to do some sandwhich code. The exercise looks like this : requir= e File.expand_path(File.dirname(__FILE__) + '/edgecase')class AboutSandwich= Code < EdgeCase::Koan def count_lines(file_name) file =3D open(file_name) count =3D 0 while line =3D file.gets count +=3D 1 end count ensure file.close if file end def test_counting_lines assert_equal 4=2C count_lines("example_file.txt") end # ------------------------------------------------------------------= def find_line(file_name) file =3D open(file_name) while line =3D file.gets return line if line.match(/e/) end ensure file.close if file end def test_finding_lines assert_equal "test\n"=2C find_line("example_file.txt") end # ------------------------------------------------------------------ # THINK ABOUT IT: # # The count_lines and find_line are similar=2C and yet different. # They both follow the pattern of "sandwich code". # # Sandwich code is code that comes in three parts: (1) the top slice # of bread=2C (2) the meat=2C and (3) the bottom slice of bread. The # bread part of the sandwich almost always goes together=2C but # the meat part changes all the time. # # Because the changing part of the sandwich code is in the middle=2C # abstracting the top and bottom bread slices to a library can be # difficult in many languages. # # (Aside for C++ programmers: The idiom of capturing allocated # pointers in a smart pointer constructor is an attempt to deal with # the problem of sandwich code for resource allocation.) # # Consider the following code: # def file_sandwich(file_name) file =3D open(file_name) yield(file) ensure file.close if file end # Now we write: def count_lines2(file_name) file_sandwich(file_name) do |file| count =3D 0 while line =3D file.gets count +=3D 1 end count end end def test_counting_lines2 assert_equal 4=2C count_lines2("example_file.txt") end # ------------------------------------------------------------------= def find_line2(file_name) # Rewrite find_line using the file_sandwich library function. end def test_finding_lines2 assert_equal __=2C find_line2("example_file.txt") end # ------------------------------------------------------------------= def count_lines3(file_name) open(file_name) do |file| count =3D 0 while line =3D file.gets count +=3D 1 end count end end def test_open_handles_the_file_sandwich_when_given_a_block assert_equal __=2C count_lines3("example_file.txt") endend But I don't get the principle.Can anyone explain this to me ? Roelof = --_ddbee70d-be91-475d-bb58-2cddf8125973_ Content-Type: text/html; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable
hello=2C
 =3B
I'm =3Bworking on ruby koans.

Now I hav= e to do some sandwhich code.
 =3B
The exercise looks like this :<= BR> =3B
require File.expand_path(File.dirname(__FILE__) + '/edgecase= ')
class AboutSandwichCode <=3B EdgeCase::Koan
 =3B def count_l= ines(file_name)
 =3B =3B =3B file =3D open(file_name)
&nb= sp=3B =3B =3B count =3D 0
 =3B =3B =3B while line = =3D file.gets
 =3B =3B =3B =3B =3B count +=3D 1
&= nbsp=3B =3B =3B end
 =3B =3B =3B count
 =3B e= nsure
 =3B =3B =3B file.close if file
 =3B end
&nb= sp=3B def test_counting_lines
 =3B =3B =3B assert_equal 4=2C= count_lines("example_file.txt")
 =3B end
 =3B # ------------= ------------------------------------------------------
 =3B def find= _line(file_name)
 =3B =3B =3B file =3D open(file_name)
&n= bsp=3B =3B =3B while line =3D file.gets
 =3B =3B =3B=  =3B =3B return line if line.match(/e/)
 =3B =3B =3B= end
 =3B ensure
 =3B =3B =3B file.close if file
&= nbsp=3B end
 =3B def test_finding_lines
 =3B =3B =3B = assert_equal "test\n"=2C find_line("example_file.txt")
 =3B end
&= nbsp=3B # -----------------------------------------------------------------= -
 =3B # THINK ABOUT IT:
 =3B #
 =3B # The count_lines= and find_line are similar=2C and yet different.
 =3B # They both fo= llow the pattern of "sandwich code".
 =3B #
 =3B # Sandwich c= ode is code that comes in three parts: (1) the top slice
 =3B # of b= read=2C (2) the meat=2C and (3) the bottom slice of bread. =3B The
&= nbsp=3B # bread part of the sandwich almost always goes together=2C but
=  =3B # the meat part changes all the time.
 =3B #
 =3B # = Because the changing part of the sandwich code is in the middle=2C
 = =3B # abstracting the top and bottom bread slices to a library can be
&n= bsp=3B # difficult in many languages.
 =3B #
 =3B # (Aside fo= r C++ programmers: The idiom of capturing allocated
 =3B # pointers = in a smart pointer constructor is an attempt to deal with
 =3B # the= problem of sandwich code for resource allocation.)
 =3B #
 = =3B # Consider the following code:
 =3B #
 =3B def file_sandw= ich(file_name)
 =3B =3B =3B file =3D open(file_name)
&nbs= p=3B =3B =3B yield(file)
 =3B ensure
 =3B =3B&nbs= p=3B file.close if file
 =3B end
 =3B # Now we write:
&nbs= p=3B def count_lines2(file_name)
 =3B =3B =3B file_sandwich(= file_name) do |file|
 =3B =3B =3B =3B =3B count =3D = 0
 =3B =3B =3B =3B =3B while line =3D file.gets
&= nbsp=3B =3B =3B =3B =3B =3B =3B count +=3D 1
&nb= sp=3B =3B =3B =3B =3B end
 =3B =3B =3B = =3B =3B count
 =3B =3B =3B end
 =3B end
 = =3B def test_counting_lines2
 =3B =3B =3B assert_equal 4=2C = count_lines2("example_file.txt")
 =3B end
 =3B # ------------= ------------------------------------------------------
 =3B def find= _line2(file_name)
 =3B =3B =3B # Rewrite find_line using the= file_sandwich library function.
 =3B end
 =3B def test_findi= ng_lines2
 =3B =3B =3B assert_equal __=2C find_line2("exampl= e_file.txt")
 =3B end
 =3B # --------------------------------= ----------------------------------
 =3B def count_lines3(file_name)<= br> =3B =3B =3B open(file_name) do |file|
 =3B =3B&n= bsp=3B =3B =3B count =3D 0
 =3B =3B =3B =3B = =3B while line =3D file.gets
 =3B =3B =3B =3B =3B&nb= sp=3B =3B count +=3D 1
 =3B =3B =3B =3B =3B end<= br> =3B =3B =3B =3B =3B count
 =3B =3B = =3B end
 =3B end
 =3B def test_open_handles_the_file_sandwich= _when_given_a_block
 =3B =3B =3B assert_equal __=2C count_li= nes3("example_file.txt")
 =3B end
end

But I don't get the = principle.
Can anyone explain this to me ?
 =3B
Roelof

=  =3B
= --_ddbee70d-be91-475d-bb58-2cddf8125973_--