Tuesday, January 31, 2006

Concrete Canvas


Instant semi-permanent structure.
Fill bag with water, activate chemical gas-pack, it inflates and hardens and is ready for use in 12-hours.

Update (1 Feb 2006):
My friend and Bob Theis (http://www.bobtheis.net/) raised these important issues:

Clever idea. Two reactions:

1. Hard to imagine a shell that thin being dimensionally stable enough for such a span in compression ( how does it resist local buckling? ). ESPECIALLY when you cover it with earth to gain some insulation ( see below ).

2. The plastic sheet interior would condense ALL the water vapor that hits it when the temperature outside is low ( despite the website claims, the insulation value of the skin should be next to nil ), where it would then freeze in colder situations. So insulation and ventilation would be serious habitability issues.

Saturday, January 14, 2006

Adding Assertions in Perl

I've been working on a Perl module that provides a set of assertion methods that will work in Perl 5.6.1 or later. (Note that Perl 5.10 should have some form of builtin support for assertions.)

So far I've implemented:

assert( expr, $optional_message ); # passes if expr is true
assert_is($$this,$that, $opt_msg); # compare with eq
assert_isnt($this,$that, $opt$msg); # Compare with ne

# all values must be == to each other
assert_num_equals($arrayref, $opt_msg);

save_data($key, $ref_to_data); # saves clone of data

# Assert that some data has (or not) the same values as the
# previsouly saved data - does a deep compare.

assert_data_not_different($key,$ref_to_data, $opt_msg);
assert_data_different($key,$ref_to_data, $opt_msg);

I've also implemented methods to set the pass and fail behaviors:

set_pass_behavior( \&my_sub ); # CODE ref

set_fail_behavior('confess'); #die with stack trace
set_fail_behavior( \&my_sub ); # CODE ref

I'm doing this for a client and am not sure if we'll be allowed to release the code publicly, but I hope so.

Saturday, January 07, 2006

Adding Unit Tests to Legacy Code

I've started adding Unit Tests to a "legacy" code library. So far, the basic approach I am taking is:

  1. Create the test harness.
  2. The first test is to compile the old code library. Of course that fails at first because of all the things the library depends on.
  3. Create enough "fake" class files that the library compiles.
  4. Pick one subroutine (method) to test, and add a test that runs that subroutine. Of course it fails because of all the missing dependencies - the subroutine under test uses a bunch of subroutines defined in others.
  5. In the test suite, create a FakeMethods class that defines stub versions of the missing external methods/subroutines, for example, the subroutine I am testing calls GetTotalAmount($cost,@items) so in the test suite I have something like this:

    sub GetTotalAmount {
    cluck('fake sub called'); # Print a stack trace showing we were called
    my($cost,@items) = @_; # Document the arguments expected
    return; # Return nothing for now

  6. Some of the fake subroutines will need to return some actual values for the subroutine I am testing to run. Add just enough input so the test passes, even when this seems ridiculous. For example, I found that one subroutine wanted the name of a file to open, and that the subroutine would run even if I passed in the name of a non-existent file. OK, that's what I did. Later, we can add a test expecting the subroutine to throw an exception if the file doesn't exist, and then add defensive code to throw the subroutine.
  7. Continue repeating steps 5 and 6 until the subroutine I am testing runs without throwing an exception.
  8. Add tests to run the subroutine with variations on its arguments and/or environment. I may need to add more fake subroutines, mock data, etc.
  9. The result is that I have a pretty clearly documented view of what the subroutine/method actually requires to run as of today.