DBC in Ruby

Has anyone attempted to implement design by contract primitives in Ruby and
if so would you be interested in sharing your experiences with me?

Ps. Here’s a copy of an email I recently sent to Matz on the subject -
perhaps you’d like to lend your support to my cause.

Greetings Matz,

[…]
I imagine you are inundated with requests for new Ruby features and I do
not want to be just another email in your box naively asking for a trivial
enhancement to Ruby that could otherwise be achieved through a deeper
understanding of the language. I assure you I have a sufficient
understanding of Ruby to venture the following request for an enhancement
that I believe would be very worth while; I hope you will feel likewise.
In a nutshell, here is my request: I would like to see native support
for Design by Contract in Ruby and in the very near future. Not to be one to
make a request without having put some thought into it, here’s a few ideas
upon which a discussion thread could be based. Should you seriously consider
pursuing this idea, I would very much like to assist in the development of
the specification.

  1. The model I would recommend, taking from Ruby’s premise of drawing on the
    best of other languages, is from The D Programming Language.

  2. The Ruby method definition would be extended to support a precondition
    and postcondition; either would be optional and if provided Ruby would
    "ensure" the precondition and postconditions were evaluated in a well
    defined manner. I would propose that the Ruby model be as flexible as
    possible and perhaps instead of the pre/post conditions being Boolean in
    nature, we leave it to the programmer to raise an exception within the
    pre-/post- condition. This would alleviate the need for the pre/post
    condition to have a return value, i.e., if they return at all the condition
    has been satisfied; on the other hand, also being Boolean in nature could be
    useful and instead have Ruby raise a predefined exception when a pre/post
    condition fails. Some debate here might be useful.

  3. The Ruby class definition would have support added for an class
    "invariant". As in D, as I understand it, the invariant would be invoked by
    Ruby automagically whenever a public method was entered and exited. The
    invariant would be private but visible to all members of the class in the
    event the programmer wished to assert the invariant manually in
    protected/private methods. The invariant would support the “super” concept
    so that derivative invariants could over-ride parent class invariant or add
    to them (by calling super), which is unlike the current D implementation, to
    the best of my knowledge.

Well Matz, I’ll stop here as I’ve taken up enough of your time before
getting an indication from you as to your interest in this enhancement to
Ruby. I sincerely hope you will consider it as Ruby combined with DBC would
provide a sorely needed solution to designing and implementing highly
reliable software and I for one would use this extensively.

[…]

Andy Hunt and I have been discussing such a language extension. DBC will
definitely be in my version of Ruby.

Andy coded a cool dbc extension but, like you, I think it merits being part
of the language.

So far:

def MyClass
def invariant

end

def my_method
pre { … }
post { … }
# code here…
end
end

MyClass#invariant is a special method, like ‘initialize’. It automatically
performs a super call.
‘pre’ executes at the start of the method, raising an exception if the block
returns false.
‘post’ executes at the end of the method, also raising an exception if the
block returns false.
‘invariant’ also gets called at the end of the method, raising an exception
if it returns false. ‘invariant’ may start a chain of ‘invariant’ method
calls through the class hierarchy.
‘invariant’ may also have to be called if a ‘super’ is within a method.

You may be able to disable/enable dbc for a class by:

MyClass.dbc( true/false )

perhaps some need to disable just ‘invariant’ calls:

MyClass.dbc_invariant( true/false )

In my version of Ruby, I’ll be making sure that there is no performance
penalty if dbc is turned off. I intend to do this by slightly modifying the
bytecode for methods when you call the dbc enable/disable method. It’s
possible to change the method bytecode start address and insert a return
before post and invariant calls to disable dbc with no loss of performance.

Thing is, I’d hate to implement this and then find out that Matz has
implemented a different scheme for his next version!

···


Justin Johnson

Hi,

···

In message “Re: DBC in Ruby.” on 02/08/07, “Justin Johnson” justinj@mobiusent.com writes:

In my version of Ruby, I’ll be making sure that there is no performance
penalty if dbc is turned off. I intend to do this by slightly modifying the
bytecode for methods when you call the dbc enable/disable method. It’s
possible to change the method bytecode start address and insert a return
before post and invariant calls to disable dbc with no loss of performance.

Thing is, I’d hate to implement this and then find out that Matz has
implemented a different scheme for his next version!

Pretty interesting. Let’s discuss before the chance we take different
path. How much should syntax help DbC? How should the core help DbC?

						matz.

And I would also like to discuss the trade offs between pre/post/invariant
failure causing Ruby to raise a corresponding exception vs. the
pre/post/invariant themselves raising a specific exception which is
indicative of what sub-condition was actually violated. There are merits to
both approaches, as I see it.

Ken.

“Yukihiro Matsumoto” matz@ruby-lang.org wrote in message
news:1028694505.982448.15154.nullmailer@picachu.netlab.jp…

Hi,

In my version of Ruby, I’ll be making sure that there is no performance
penalty if dbc is turned off. I intend to do this by slightly modifying
the
bytecode for methods when you call the dbc enable/disable method. It’s
possible to change the method bytecode start address and insert a return
before post and invariant calls to disable dbc with no loss of
performance.

···

In message “Re: DBC in Ruby.” > on 02/08/07, “Justin Johnson” justinj@mobiusent.com writes:

Thing is, I’d hate to implement this and then find out that Matz has
implemented a different scheme for his next version!

Pretty interesting. Let’s discuss before the chance we take different
path. How much should syntax help DbC? How should the core help DbC?

matz.