170 lines
3.6 KiB
Ruby
170 lines
3.6 KiB
Ruby
|
require File.expand_path(File.dirname(__FILE__) + '/neo')
|
||
|
|
||
|
class AboutClassMethods < Neo::Koan
|
||
|
class Dog
|
||
|
end
|
||
|
|
||
|
def test_objects_are_objects
|
||
|
fido = Dog.new
|
||
|
assert_equal __, fido.is_a?(Object)
|
||
|
end
|
||
|
|
||
|
def test_classes_are_classes
|
||
|
assert_equal __, Dog.is_a?(Class)
|
||
|
end
|
||
|
|
||
|
def test_classes_are_objects_too
|
||
|
assert_equal __, Dog.is_a?(Object)
|
||
|
end
|
||
|
|
||
|
def test_objects_have_methods
|
||
|
fido = Dog.new
|
||
|
assert fido.methods.size > _n_
|
||
|
end
|
||
|
|
||
|
def test_classes_have_methods
|
||
|
assert Dog.methods.size > _n_
|
||
|
end
|
||
|
|
||
|
def test_you_can_define_methods_on_individual_objects
|
||
|
fido = Dog.new
|
||
|
def fido.wag
|
||
|
:fidos_wag
|
||
|
end
|
||
|
assert_equal __, fido.wag
|
||
|
end
|
||
|
|
||
|
def test_other_objects_are_not_affected_by_these_singleton_methods
|
||
|
fido = Dog.new
|
||
|
rover = Dog.new
|
||
|
def fido.wag
|
||
|
:fidos_wag
|
||
|
end
|
||
|
|
||
|
assert_raise(___) do
|
||
|
rover.wag
|
||
|
end
|
||
|
end
|
||
|
|
||
|
# ------------------------------------------------------------------
|
||
|
|
||
|
class Dog2
|
||
|
def wag
|
||
|
:instance_level_wag
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def Dog2.wag
|
||
|
:class_level_wag
|
||
|
end
|
||
|
|
||
|
def test_since_classes_are_objects_you_can_define_singleton_methods_on_them_too
|
||
|
assert_equal __, Dog2.wag
|
||
|
end
|
||
|
|
||
|
def test_class_methods_are_independent_of_instance_methods
|
||
|
fido = Dog2.new
|
||
|
assert_equal __, fido.wag
|
||
|
assert_equal __, Dog2.wag
|
||
|
end
|
||
|
|
||
|
# ------------------------------------------------------------------
|
||
|
|
||
|
class Dog
|
||
|
attr_accessor :name
|
||
|
end
|
||
|
|
||
|
def Dog.name
|
||
|
@name
|
||
|
end
|
||
|
|
||
|
def test_classes_and_instances_do_not_share_instance_variables
|
||
|
fido = Dog.new
|
||
|
fido.name = "Fido"
|
||
|
assert_equal __, fido.name
|
||
|
assert_equal __, Dog.name
|
||
|
end
|
||
|
|
||
|
# ------------------------------------------------------------------
|
||
|
|
||
|
class Dog
|
||
|
def Dog.a_class_method
|
||
|
:dogs_class_method
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def test_you_can_define_class_methods_inside_the_class
|
||
|
assert_equal __, Dog.a_class_method
|
||
|
end
|
||
|
|
||
|
# ------------------------------------------------------------------
|
||
|
|
||
|
LastExpressionInClassStatement = class Dog
|
||
|
21
|
||
|
end
|
||
|
|
||
|
def test_class_statements_return_the_value_of_their_last_expression
|
||
|
assert_equal __, LastExpressionInClassStatement
|
||
|
end
|
||
|
|
||
|
# ------------------------------------------------------------------
|
||
|
|
||
|
SelfInsideOfClassStatement = class Dog
|
||
|
self
|
||
|
end
|
||
|
|
||
|
def test_self_while_inside_class_is_class_object_not_instance
|
||
|
assert_equal __, Dog == SelfInsideOfClassStatement
|
||
|
end
|
||
|
|
||
|
# ------------------------------------------------------------------
|
||
|
|
||
|
class Dog
|
||
|
def self.class_method2
|
||
|
:another_way_to_write_class_methods
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def test_you_can_use_self_instead_of_an_explicit_reference_to_dog
|
||
|
assert_equal __, Dog.class_method2
|
||
|
end
|
||
|
|
||
|
# ------------------------------------------------------------------
|
||
|
|
||
|
class Dog
|
||
|
class << self
|
||
|
def another_class_method
|
||
|
:still_another_way
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def test_heres_still_another_way_to_write_class_methods
|
||
|
assert_equal __, Dog.another_class_method
|
||
|
end
|
||
|
|
||
|
# THINK ABOUT IT:
|
||
|
#
|
||
|
# The two major ways to write class methods are:
|
||
|
# class Demo
|
||
|
# def self.method
|
||
|
# end
|
||
|
#
|
||
|
# class << self
|
||
|
# def class_methods
|
||
|
# end
|
||
|
# end
|
||
|
# end
|
||
|
#
|
||
|
# Which do you prefer and why?
|
||
|
# Are there times you might prefer one over the other?
|
||
|
|
||
|
# ------------------------------------------------------------------
|
||
|
|
||
|
def test_heres_an_easy_way_to_call_class_methods_from_instance_methods
|
||
|
fido = Dog.new
|
||
|
assert_equal __, fido.class.another_class_method
|
||
|
end
|
||
|
|
||
|
end
|