930345d6a9cc12bbc1219ccecc04eeddb220d413
[ruby_koans.git] / src / about_class_methods.rb
1 require File.expand_path(File.dirname(__FILE__) + '/edgecase')
2
3 class AboutClassMethods < EdgeCase::Koan
4   class Dog
5   end
6
7   def test_objects_are_objects
8     fido = Dog.new
9     assert_equal __(true), fido.is_a?(Object)
10   end
11
12   def test_classes_are_classes
13     assert_equal __(true), Dog.is_a?(Class)
14   end
15
16   def test_classes_are_objects_too
17     assert_equal __(true), Dog.is_a?(Object)
18   end
19
20   def test_objects_have_methods
21     fido = Dog.new
22     assert fido.methods.size > _n_(30)
23   end
24
25   def test_classes_have_methods
26     assert Dog.methods.size > _n_(40)
27   end
28
29   def test_you_can_define_methods_on_individual_objects
30     fido = Dog.new
31     def fido.wag
32       :fidos_wag
33     end
34     assert_equal __(:fidos_wag), fido.wag
35   end
36
37   def test_other_objects_are_not_affected_by_these_singleton_methods
38     fido = Dog.new
39     rover = Dog.new
40     def fido.wag
41       :fidos_wag
42     end
43
44     assert_raise(___(NoMethodError)) do
45       rover.wag
46     end
47   end
48
49   # ------------------------------------------------------------------
50   
51   class Dog2
52     def wag
53       :instance_level_wag
54     end
55   end
56
57   def Dog2.wag
58     :class_level_wag
59   end
60
61   def test_since_classes_are_objects_you_can_define_singleton_methods_on_them_too
62     assert_equal __(:class_level_wag), Dog2.wag
63   end
64
65   def test_class_methods_are_independent_of_instance_methods
66     fido = Dog2.new
67     assert_equal __(:instance_level_wag), fido.wag
68     assert_equal __(:class_level_wag), Dog2.wag
69   end
70
71   # ------------------------------------------------------------------
72
73   class Dog
74     attr_accessor :name
75   end
76
77   def Dog.name
78     @name
79   end
80
81   def test_classes_and_instances_do_not_share_instance_variables
82     fido = Dog.new
83     fido.name = "Fido"
84     assert_equal __("Fido"), fido.name
85     assert_equal __(nil), Dog.name
86   end
87
88   # ------------------------------------------------------------------
89
90   class Dog
91     def Dog.a_class_method
92       :dogs_class_method
93     end
94   end
95
96   def test_you_can_define_class_methods_inside_the_class
97     assert_equal __(:dogs_class_method), Dog.a_class_method
98   end
99       
100
101   # ------------------------------------------------------------------
102
103   LastExpressionInClassStatement = class Dog
104                                      21
105                                    end
106   
107   def test_class_statements_return_the_value_of_their_last_expression
108     assert_equal __(21), LastExpressionInClassStatement
109   end
110
111   # ------------------------------------------------------------------
112
113   SelfInsideOfClassStatement = class Dog
114                                  self
115                                end
116
117   def test_self_while_inside_class_is_class_object_not_instance
118     assert_equal __(true), Dog == SelfInsideOfClassStatement
119   end
120
121   # ------------------------------------------------------------------
122
123   class Dog
124     def self.class_method2
125       :another_way_to_write_class_methods
126     end
127   end
128
129   def test_you_can_use_self_instead_of_an_explicit_reference_to_dog
130     assert_equal __(:another_way_to_write_class_methods), Dog.class_method2
131   end
132
133   # ------------------------------------------------------------------
134
135   class Dog
136     class << self
137       def another_class_method
138         :still_another_way
139       end
140     end
141   end
142
143   def test_heres_still_another_way_to_write_class_methods
144     assert_equal __(:still_another_way), Dog.another_class_method
145   end
146
147   # THINK ABOUT IT:
148   #
149   # The two major ways to write class methods are:
150   #   class Demo
151   #     def self.method
152   #     end
153   #
154   #     class << self
155   #       def class_methods
156   #       end
157   #     end
158   #   end
159   #
160   # Which do you prefer and why?
161   # Are there times you might prefer one over the other?
162
163   # ------------------------------------------------------------------
164
165   def test_heres_an_easy_way_to_call_class_methods_from_instance_methods
166     fido = Dog.new
167     assert_equal __(:still_another_way), fido.class.another_class_method
168   end
169
170 end