> I have not given up on the idea of implementing a DBC module in > Ruby. But every time I get into it, it makes my brain itch. I > want to (have to!) make the conditions heritable, but I want to > make it easy to use as well... I've given some thought to this too and my conclusion, so far, has been to change the Ruby interpreter code. class Gem use DBC @carats attr_accessor :carats def invariant @carats > 10 end def pre_value(price) price > 0 end def value( price ) @carats * price end def post_value(price, ret) ret > 40 # a little bit made up condition end end class Ruby < Gem def value( price ) @carats ** price end end class PieceOfWorthlessGlass < Gem # like in nethack def invariant @carats > 0 end end stone = Gem.new stone.carats = 5 # should raise InvariantFailed stone.carats = 15 stone.value( 0 ) # should raise PreConditionFailed stone.value( 1 ) # should raise PostConditionFailed stone.value( 2 ) # should raise PostConditionFailed stone.value( 3 ) stone = Ruby.new stone.carats = 5 # should raise InvariantFailed stone.carats = 15 stone.value( 0 ) # should raise PreConditionFailed stone.value( 1 ) # should raise PostConditionFailed stone.value( 2 ) stone.value( 3 ) stone = PieceOfWorthlessGlass.new stone.carats = 5 stone.value( 0 ) # should raise PreConditionFailed stone.value( 1 ) # should raise PostConditionFailed stone.value( 2 ) # should raise PostConditionFailed stone.value( 3 ) # should raise PostConditionFailed stone.value( 9 ) To make this happen we can't use the trick to execute some 'changeMethodCallsToDBCStubs()' directly (as Ruby code) as we discussed in earlier threads. It will break with inheritance and even when we add something to the class. So the options are (should I say include): 1) to change the method calling to check for DBC functions (pre_method, post_method and invariant) and the normal first singleton, self, modules and parents order works out the inheritance of DBC. 2) to change the inner workings of 'def' to replace automatically real methods with {pre(args) method(args) post(args) invariant} type of code I think I prefer the second one if it's applicable at all. The performance penalty would be minimal (or as small as possible :?). For those who're going to note that the second way wouldn't work when we add special DBC-checkers to singleton classes or just afterwards, I could say that it does work. So imagine there has been no pre_value DBC precondition checker written earlier (I'm too tired to write real example). When "executing" the 'def' in class << stone def pre_value(price) price > 100 end end will restub the value by executing class << stone def value(price) raise PreConditionFailed unless pre_value # ### orig_value(price) raise PostConditionFailed unless post_value raise InvariantFailed unless invariant end end behind the curtains. The earlier stub didn't have the marked line before, but now we see that there exists a proper pre_condition checker we can use, thus the new version incorporates new call. Even this version isn't elegant for various reasons, but most notably because Class.methods would list DBC-methods too. But this is probably minor thing now (and probably can be hacked easily). In any case, I'd like to make it clear that I would be really happy to see Ruby with more or less built-in DBC support (widely used). - Aleksi