From: matz@... (Yukihiro Matsumoto) Date: 2000-04-01T03:22:19+09:00 Subject: [ruby-talk:02308] Re: DBC Hi, In message "[ruby-talk:02298] Re: DBC" on 00/03/31, Andrew Hunt writes: |My Rube-Goldberg attempt used tracefunc to hook into the dispatcher, |so that I could check every method call and see if a pre/post condition |existed and then call it. This also gave me the opportunity to call |invariant on exit from every method call. The tracefunc may be a performance killer. I'm not sure whether using reflection is better or not. Here's the basic concept. module DBC def DBC::assertion(mod) methods = mod.instance_methods methods.each do |m| next if m =~ /__(pre|post|orig)$/ pre = m+"__pre" post = m+"__post" if methods.include?(pre) and methods.include?(post) mod.module_eval %{ alias #{m}__orig #{m} def #{m}(*args, &block) #{m}__pre(*args) result = #{m}__orig(*args, &block) #{m}__post(result, *args) result end } elsif methods.include?(pre) mod.module_eval %{ alias #{m}__orig #{m} def #{m}(*args, &block) #{m}__pre(*args) #{m}__orig(*args, &block) end } elsif methods.include?(post) mod.module_eval %{ alias #{m}__orig #{m} def #{m}(*args, &block) result = #{m}__orig(*args, &block) #{m}__post(result, *args) result end } end end end end class Foo include DBC def foo__pre p "pre" end def foo__post(result) p "post" end def foo p "foo" end DBC::assertion(self) end foo = Foo.new foo.foo By the way, what DBC stand for? matz.