Dave Thomas <Dave / PragmaticProgrammer.com> wrote:
>
>Eric Sven Ristad <ristad / mnemonic.com> writes:
[...]
>   DEBUG = false  # or true
>
>   def assert
>     if DEBUG
>       result = yield
>       raise "Assertion failed" if !result
>     end
>   end
>
>   assert { 1 == 1 }
>
>   assert { 1 == 2 }
>
>This defers the evaluation of the code in the block until the method
>'assert' can determine if DEBUG is set to true.
[...]

You can also write that as:

    DEBUG = false # or true

    if DEBUG
      def assert
        raise "Assertion failed!" if not yield
      end
    else
      def assert
      end
    end

Theoretically moving the test of whether DEBUG is true
or false to initialization should be marginally
faster.  I am not sure that matters, and I am only
mentioning it in case someone out there didn't know how
easy it is to create a compatibility layer by
conditionally loading different ways of supporting the
same API.  In that light the following link on writing
portable code may be of general interest:

http://kt.linuxcare.com/kernel-traffic/kt20000501_65.epl#5

The moral is that you define an API that you can write to,
and write to that in the bulk of your code.  Then you have
a small compatibility layer which translates the standard
API to the current platform.  Which is what Dave Thomas was
doing by hiding away the test in an assert function, and I
was doing by defining the assert macro appropriately
depending on the constant.

What most people try, that doesn't work so well is scattering
tests through their code for the various cases.  Intertwining
the portability logic with everything else, and leaving you
just hoping that you remembered all of the places that you
have to check each fact about portability...

Cheers,
Ben
_________________________________________________________________
Get your FREE download of MSN Explorer at http://explorer.msn.com