updated koans with latest src
[ruby_koans.git] / koans / about_iteration.rb
1 require File.expand_path(File.dirname(__FILE__) + '/edgecase')
2
3 class AboutIteration < EdgeCase::Koan
4
5   # -- An Aside ------------------------------------------------------
6   # Ruby 1.8 stores names as strings. Ruby 1.9 stores names as
7   # symbols. So we use a version dependent method "as_name" to convert
8   # to the right format in the koans.  We will use "as_name" whenever
9   # comparing to lists of methods.
10
11   in_ruby_version("1.8") do
12     def as_name(name)
13       name.to_s
14     end
15   end
16
17   in_ruby_version("1.9") do
18     def as_name(name)
19       name.to_sym
20     end
21   end
22
23   # Ok, now back to the Koans.
24   # -------------------------------------------------------------------
25
26   def test_each_is_a_method_on_arrays
27     assert_equal __, [].methods.include?(as_name(:each))
28   end
29
30   def test_iterating_with_each
31     array = [1, 2, 3]
32     sum = 0
33     array.each do |item|
34       sum += item
35     end
36     assert_equal __, sum
37   end
38
39   def test_each_can_use_curly_brace_blocks_too
40     array = [1, 2, 3]
41     sum = 0
42     array.each { |item|
43       sum += item
44     }
45     assert_equal __, sum
46   end
47
48   def test_break_works_with_each_style_iterations
49     array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
50     sum = 0
51     array.each { |item|
52       break if item > 3
53       sum += item
54     }
55     assert_equal __, sum
56   end
57
58   def test_collect_transforms_elements_of_an_array
59     array = [1, 2, 3]
60     new_array = array.collect { |item| item + 10 }
61     assert_equal __, new_array
62
63     # NOTE: 'map' is another name for the 'collect' operation
64     another_array = array.map { |item| item + 10 }
65     assert_equal __, another_array
66   end
67
68   def test_select_selects_certain_items_from_an_array
69     array = [1, 2, 3, 4, 5, 6]
70
71     even_numbers = array.select { |item| (item % 2) == 0 }
72     assert_equal __, even_numbers
73
74     # NOTE: 'find_all' is another name for the 'select' operation
75     more_even_numbers = array.find_all { |item| (item % 2) == 0 }
76     assert_equal __, more_even_numbers
77   end
78
79   def test_find_locates_the_first_element_matching_a_criteria
80     array = ["Jim", "Bill", "Clarence", "Doug", "Eli"]
81
82     assert_equal __, array.find { |item| item.size > 4 }
83   end
84
85   def test_inject_will_blow_your_mind
86     result = [2, 3, 4].inject(0) { |sum, item| sum + item }
87     assert_equal __, result
88
89     result2 = [2, 3, 4].inject(1) { |sum, item| sum * item }
90     assert_equal __, result2
91
92     # Extra Credit:
93     # Describe in your own words what inject does.
94   end
95
96   def test_all_iteration_methods_work_on_any_collection_not_just_arrays
97     # Ranges act like a collection
98     result = (1..3).map { |item| item + 10 }
99     assert_equal __, result
100
101     # Files act like a collection of lines
102     File.open("example_file.txt") do |file|
103       upcase_lines = file.map { |line| line.strip.upcase }
104       assert_equal __, upcase_lines
105     end
106
107     # NOTE: You can create your own collections that work with each,
108     # map, select, etc.
109   end
110
111   # Bonus Question:  In the previous koan, we saw the construct:
112   #
113   #   File.open(filename) do |file|
114   #     # code to read 'file'
115   #   end
116   #
117   # Why did we do it that way instead of the following?
118   #
119   #   file = File.open(filename)
120   #   # code to read 'file'
121   #
122   # When you get to the "AboutSandwichCode" koan, recheck your answer.
123
124 end