forked from sathish316/metaprogramming_koans
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adding initial metaprogramming koans
- Loading branch information
1 parent
d1494a6
commit e4dff77
Showing
21 changed files
with
1,132 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
dist | ||
.project_env.rc | ||
.path_progress | ||
*.rbc | ||
.idea |
This file was deleted.
Oops, something went wrong.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
require File.expand_path(File.dirname(__FILE__) + '/edgecase') | ||
|
||
class AboutBinding < EdgeCase::Koan | ||
|
||
class Foo | ||
def initialize | ||
@ivar = 22 | ||
end | ||
|
||
def bar(param) | ||
lvar = 11 | ||
binding | ||
end | ||
end | ||
|
||
def test_binding_binds_method_parameters | ||
binding = Foo.new.bar(99) | ||
assert_equal 99, eval("param", binding) | ||
end | ||
|
||
def test_binding_binds_local_vars | ||
binding = Foo.new.bar(99) | ||
assert_equal 11, eval("lvar", binding) | ||
end | ||
|
||
def test_binding_binds_instance_vars | ||
binding = Foo.new.bar(99) | ||
assert_equal 22, eval("@ivar", binding) | ||
end | ||
|
||
def test_binding_binds_blocks | ||
binding = Foo.new.bar(99) { 33 } | ||
assert_equal 33, eval("yield", binding) | ||
end | ||
|
||
def test_binding_binds_self | ||
foo = Foo.new | ||
binding = foo.bar(99) | ||
assert_equal foo, eval("self", binding) | ||
end | ||
|
||
def n_times(n) | ||
lambda {|value| n * value} | ||
end | ||
|
||
def test_lambda_binds_to_the_surrounding_context | ||
two_times = n_times(2) | ||
assert_equal 6, two_times.call(3) | ||
end | ||
|
||
def count_with_increment(start, inc) | ||
lambda { start += inc} | ||
end | ||
|
||
def test_lambda_remembers_state_of_bound_variables | ||
counter = count_with_increment(7, 3) | ||
assert_equal 10, counter.call | ||
assert_equal 13, counter.call | ||
assert_equal 16, counter.call | ||
end | ||
|
||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
require File.expand_path(File.dirname(__FILE__) + '/edgecase') | ||
|
||
class AboutBlocks < EdgeCase::Koan | ||
|
||
def test_calling_a_lambda | ||
l = lambda {|a| a + 1} | ||
assert_equal 100, l.call(99) | ||
end | ||
|
||
def test_calling_a_proc | ||
p = Proc.new {|a| a + 1} | ||
assert_equal 100, p.call(99) | ||
end | ||
|
||
def convert(&block) | ||
block | ||
end | ||
|
||
def test_block_is_proc | ||
b = convert {|a| a + 1} | ||
assert_equal Proc, b.class | ||
assert_equal 100, b.call(99) | ||
end | ||
|
||
def test_proc_takes_fewer_or_more_arguments | ||
p = Proc.new {|a, b, c| a.to_i + b.to_i + c.to_i} | ||
assert_equal 3 , p.call(1,2) | ||
assert_equal 6, p.call(1,2,3,4) | ||
end | ||
|
||
def test_lambda_does_not_take_fewer_or_more_arguments | ||
l = lambda {|a, b, c| a.to_i + b.to_i + c.to_i} | ||
assert_raises(ArgumentError) do | ||
l.call(1, 2) | ||
end | ||
|
||
assert_raises(ArgumentError) do | ||
l.call(1,2,3,4) | ||
end | ||
end | ||
|
||
def method(lambda_or_proc) | ||
lambda_or_proc.call | ||
:from_method | ||
end | ||
|
||
def test_return_inside_lambda_returns_from_the_lambda | ||
l = lambda { return :from_lambda } | ||
result = method(l) | ||
assert_equal :from_method, result | ||
end | ||
|
||
def test_return_inside_proc_returns_from_the_context | ||
p = Proc.new { return :from_proc } | ||
result = method(p) | ||
# The execution never reaches this line because Proc returns | ||
# outside the test method | ||
assert_equal __, p.call | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
require File.expand_path(File.dirname(__FILE__) + '/edgecase') | ||
|
||
class AboutClassAsConstant < EdgeCase::Koan | ||
|
||
class Foo | ||
def say_hello | ||
"Hi" | ||
end | ||
end | ||
|
||
def test_defined_tells_if_a_class_is_defined_or_not | ||
assert_not_nil defined?(Foo) | ||
assert_nil defined?(Bar) | ||
end | ||
|
||
def test_class_is_a_constant | ||
assert_equal "constant", defined?(Foo) | ||
end | ||
|
||
def test_class_constant_can_be_assigned_to_var | ||
my_class = Foo | ||
assert_equal "Hi", my_class.new.say_hello | ||
end | ||
|
||
@@return_value_of_class = | ||
class Baz | ||
def say_hi | ||
"Hello" | ||
end | ||
99 | ||
end | ||
|
||
def test_class_definitions_are_active | ||
assert_equal 99, @@return_value_of_class | ||
end | ||
|
||
@@self_inside_a_class = | ||
class Baz | ||
def say_hi | ||
"Hi" | ||
end | ||
self | ||
end | ||
|
||
def test_self_inside_class_is_class_itself | ||
assert_equal Baz, @@self_inside_a_class | ||
end | ||
|
||
def test_class_is_an_object_of_type_class_and_can_be_created_dynamically | ||
cls = Class.new | ||
assert_match /Class/, cls.to_s | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
require File.expand_path(File.dirname(__FILE__) + '/edgecase') | ||
|
||
class AboutClassInheritance < EdgeCase::Koan | ||
|
||
def test_singleton_class_can_be_used_to_define_singleton_methods | ||
animal = "cat" | ||
class << animal | ||
def speak | ||
"miaow" | ||
end | ||
end | ||
assert_equal "miaow", animal.speak | ||
end | ||
|
||
class Foo | ||
class << self | ||
def say_hello | ||
"Hello" | ||
end | ||
end | ||
end | ||
|
||
def test_singleton_class_can_be_used_to_define_class_methods | ||
assert_equal "Hello", Foo.say_hello | ||
end | ||
|
||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
require File.expand_path(File.dirname(__FILE__) + '/edgecase') | ||
|
||
class AboutClassMethods < EdgeCase::Koan | ||
|
||
class Foo | ||
def self.say_hello | ||
"Hello" | ||
end | ||
end | ||
|
||
def test_class_is_an_instance_of_class_Class | ||
assert_equal true, Foo.class == Class | ||
end | ||
|
||
def test_class_methods_are_just_singleton_methods_on_the_class | ||
assert_equal "Hello", Foo.say_hello | ||
end | ||
|
||
def test_classes_are_not_special_and_are_just_like_other_objects | ||
assert_equal true, Foo.is_a?(Object) | ||
assert_equal true, Foo.superclass == Object | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
require File.expand_path(File.dirname(__FILE__) + '/edgecase') | ||
|
||
class AboutDefineMethod < EdgeCase::Koan | ||
|
||
class Example | ||
def start | ||
def stop | ||
:stopped | ||
end | ||
:started | ||
end | ||
end | ||
|
||
def test_methods_can_define_other_methods | ||
o = Example.new | ||
assert_raises(NoMethodError) do | ||
o.stop | ||
end | ||
|
||
o.start | ||
|
||
assert_equal :stopped, o.stop | ||
end | ||
|
||
class Example | ||
def foo | ||
def foo | ||
:new_value | ||
end | ||
:first_value | ||
end | ||
end | ||
|
||
def test_methods_can_redefine_themselves | ||
o = Example.new | ||
assert_equal :first_value, o.foo | ||
assert_equal :new_value, o.foo | ||
end | ||
|
||
class Multiplier | ||
def self.create_multiplier(n) | ||
define_method "times_#{n}" do |val| | ||
val * n | ||
end | ||
end | ||
|
||
10.times {|i| create_multiplier(i) } | ||
end | ||
|
||
def test_define_method_creates_methods_dynamically | ||
m = Multiplier.new | ||
assert_equal 30, m.times_3(10) | ||
assert_equal 60, m.times_6(10) | ||
assert_equal 90, m.times_9(10) | ||
end | ||
|
||
module Accessor | ||
def my_writer(name) | ||
ivar_name = "@#{name}" | ||
define_method "#{name}=" do |value| | ||
#Write code here to set value of ivar | ||
instance_variable_set(ivar_name, value) | ||
end | ||
end | ||
|
||
def my_reader(name) | ||
ivar_name = "@#{name}" | ||
define_method name do | ||
#Write code here to get value of ivar | ||
instance_variable_get(ivar_name) | ||
end | ||
end | ||
end | ||
|
||
class Cat | ||
extend Accessor | ||
my_writer :name | ||
my_reader :name | ||
end | ||
|
||
def test_instance_variable_set_and_instance_variable_get_can_be_used_to_access_ivars | ||
cat = Cat.new | ||
cat.name = 'Fred' | ||
assert_equal 'Fred', cat.name | ||
end | ||
end | ||
|
Oops, something went wrong.