Fwd: Ruby Quiz Corrections

Some new coverage of an old but favorite quiz.

James Edward G. II

Begin forwarded message:

On Tue, 6 Feb 2007, James Edward G. II wrote:

Some new coverage of an old but favorite quiz.

thanks james

behind). Anyways, I think that the koans are missing or have incorrect
assertions.

I’m not sure if you post corrections, or if you can forward this on to the
author, but I posted some of the problems that I discovered while solving
the quiz at http://kinderman.net/articles/2007/02/05/
problems-with-the-metakoans-rb-ruby-quiz.

hi ryan-

yeah. interesting point. in fact, you are right but for reasons you
might
not suspect. regarding the

assert{ (o.a = nil) == nil }

assertions you’ll note they all start when default values are being
provided,
what’d i’d meant to testing here was that the setter should always
return the
new value and not the one provided as a default. obviously that’s a
mistake
since, in ruby, setters always do this, one cannot change it:

harp:~ > cat a.rb
def a=(x) 42 end
p(self.a = ‘forty-two’)

harp:~ > ruby a.rb
“forty-two”

so the best thing would be to simple remove those test or, as you point
out,
do a two step test. i chose the latter for the new version.

regarding incrementing 42 - that’s impossible! :wink: see if you like my
new
approach. it acheives the same end goal, which is valuable:

harp: ~> cat a.rb

metakoans.rb is an arduous set of exercises designed to stretch

meta-programming muscle. the focus is on a single method

‘attribute’ which

behaves much like the built-in ‘attr’, but whose properties require

deleving

deep into the depths of meta-ruby. usage of the ‘attribute’ method

follows

the general form of

class C

attribute ‘a’

end

o = C::new

o.a = 42 # setter

o.a # getter

o.a? # query

but reaches much farther than the standard ‘attr’ method as you

will see

shortly.

your path, should you choose to follow it, is to write a single

file

‘knowledge.rb’ implementing all functionality required by the koans

below.

as a student of meta-programming your course will be guided by a

guru whose

wisdom and pithy sayings will assist you on your journey.

a successful student will eventually be able to do this

harp:~ > ruby metakoans.rb knowledge.rb

koan_1 has expanded your awareness

koan_2 has expanded your awareness

koan_3 has expanded your awareness

koan_4 has expanded your awareness

koan_5 has expanded your awareness

koan_6 has expanded your awareness

koan_7 has expanded your awareness

koan_8 has expanded your awareness

koan_9 has expanded your awareness

mountains are again merely mountains

module MetaKoans

‘attribute’ must provide getter, setter, and query to instances

 def koan_1
   c = Class::new {
     attribute 'a'
   }

   o = c::new

   assert{ not o.a? }
   assert{ o.a = 31 }
   assert{ o.a == 31 }
   assert{ o.a? }
 end

‘attribute’ must provide getter, setter, and query to classes

 def koan_2
   c = Class::new {
     class << self
       attribute 'a'
     end
   }

   assert{ not c.a? }
   assert{ c.a = 32 }
   assert{ c.a == 32 }
   assert{ c.a? }
 end

‘attribute’ must provide getter, setter, and query to modules at

module

level

 def koan_3
   m = Module::new {
     class << self
       attribute 'a'
     end
   }

   assert{ not m.a? }
   assert{ m.a = 33 }
   assert{ m.a == 33 }
   assert{ m.a? }
 end

‘attribute’ must provide getter, setter, and query to modules which

operate

corectly when they are included by or extend objects

 def koan_4
   m = Module::new {
     attribute 'a'
   }

   c = Class::new {
     include m
     extend m
   }

   o = c::new

   assert{ not o.a? }
   assert{ o.a = 34 }
   assert{ o.a == 34 }
   assert{ o.a? }

   assert{ not c.a? }
   assert{ c.a = 35 }
   assert{ c.a == 35 }
   assert{ c.a? }
 end

‘attribute’ must provide getter, setter, and query to singleton

objects

 def koan_5
   o = Object::new

   class << o
     attribute 'a'
   end

   assert{ not o.a? }
   assert{ o.a = 36 }
   assert{ o.a == 36 }
   assert{ o.a? }
 end

‘attribute’ must provide a method for providing a default value as

hash

 def koan_6
   c = Class::new {
     attribute 'a' => 37
   }

   o = c::new

   assert{ o.a == 37 }
   assert{ o.a? }
   assert{ o.a = nil; o.a == nil }
   assert{ not o.a? }
 end

‘attribute’ must provide a method for providing a default value as

block

which is evaluated at instance level

 def koan_7
   c = Class::new {
     attribute('a'){ b }
     def b
       38
     end
   }

   o = c::new

   assert{ o.b == 38 }
   assert{ o.a == 38 }
   assert{ o.a? }
   assert{ o.a = nil; o.a == nil }
   assert{ not o.a? }
   assert{ o.b == 38 }
 end

‘attribute’ must provide inheritence of default values at both

class and

instance levels

 def koan_8
   b = Class::new {
     class << self
       attribute 'a' => 39
       attribute('b'){ a }
     end
     attribute 'a' => 40
     attribute('b'){ a }
   }

   c = Class::new b

   assert{ c.b == 39 }
   assert{ c.a == 39 }
   assert{ c.a? }
   assert{ c.a = nil; c.a == nil }
   assert{ not c.a? }
   assert{ c.b == 39 }

   o = c::new

   assert{ o.b == 40 }
   assert{ o.a == 40 }
   assert{ o.a? }
   assert{ o.a = nil; o.a == nil }
   assert{ not o.a? }
   assert{ o.b == 40 }
 end

into the void

 def koan_9
   b = Class::new {
     class << self
       attribute 'a' => 41
       attribute('b'){ a }
     end
     include Module::new {
       attribute 'a' => 42
       attribute('b'){ a }
     }
   }

   c = Class::new b

   assert{ c.b == 41 }
   assert{ c.a == 41 }
   assert{ c.a? }
   assert{ c.a = nil; c.a == nil }
   assert{ not c.a? }
   assert{ c.b == 41 }

   o = c::new

   assert{ o.b == 42 }
   assert{ o.a == 42 }
   assert{ o.a? }
   assert{ o.a = nil; o.a == nil }
   assert{ not o.a? }
   assert{ o.b == 42 }
 end

 def assert() raise unless yield end

end

class MetaStudent
def initialize knowledge
require knowledge
end
def ponder koan
begin
send koan
true
rescue => e
STDERR.puts %Q[#{ e.message } (#{ e.class })\n#{
e.backtrace.join 10.chr }]
false
end
end
end

class MetaGuru
require “singleton”
include Singleton

 def enlighten student
   student.extend MetaKoans

   koans = student.methods.grep(%r/koan/).sort

   attainment = nil

   koans.each do |koan|
     awakened = student.ponder koan
     if awakened
       puts "#{ koan } has expanded your awareness"
       attainment = koan
     else
       puts "#{ koan } still requires meditation"
       break
     end
   end

   puts(
     case attainment
       when nil
         "mountains are merely mountains"
       when 'koan_1', 'koan_2'
         "learn the rules so you know how to break them properly"
       when 'koan_3', 'koan_4'
         "remember that silence is sometimes the best answer"
       when 'koan_5', 'koan_6'
         "sleep is the best meditation"
       when 'koan_7'
         "when you lose, don't lose the lesson"
       when 'koan_8'
         "things are not what they appear to be: nor are they 

otherwise"
else
“mountains are again merely mountains”
end
)
end
def self::method_missing m, *a, &b
instance.send m, *a, &b
end
end

knowledge = ARGV.shift or abort “#{ $0 } knowledge.rb”
student = MetaStudent::new knowledge
MetaGuru.enlighten student

-a