Rob,

On Nov 23, 2004, at 12:50 PM, Rob Kinyon wrote:
I'm a little confused as to why one would need pre- and
post-conditions at all. The "ensure" block would seem to handle the
whole thing as it is both the pre- and post-condition to the "using"
block. (What about aliasing "doing" to "using"?)

There may be preconditions which need to be true prior to running the code, but which are false after the code is run. For instance, deleting a file. I want to be sure its there first, then delete it, and afterwards the file is gone so the pre-condition would fail.


Also the ensure works by being false before the using block and then true afterwards, so using it as a pre-condition would be difficult IMO since you would have to define the negative rather than the positive.


Steve




The only thing I can see being useful is allowing for more than one
"ensure" and more than one "using" block. This would allow me to write
something like:

step Foo =>
    ensure { -f '/net' }
    ensure { -f '/net/foo' }
    ensure { The actual thing I care about }
    using { Do something here }
    using { Do something else here}
;

The benefit is that you can do things like:

sub foo { blahblah }
sub bar { blahblah }

step Foo =>
    ensure \&foo
    ensure \&bar
    using { Do something }
;

And have reusable ensure clauses. Sure, you could do:
step Foo =>
    ensure { foo() && bar() }
    using { Do something }
;

But, there's no reason not to allow it, that I can think of. This is
especially true when treating them as assertions.

*thinks a little bit*

I've been thinking about what to do if either the C<ensure> or the
<using>
blocks are missing.  Currently the module throws an exception, but I
don't
think that's right.  In an earlier draft of the module, I had an
"ALWAYS"
variant that ran the C<using> clause whether or not the C<ensure> was
present.  Surely

  step withoutUsing =>
    ensure { -f '/boot/vmunix' }
  ;

should be treated as an assertion: if it's true, go on, if false,
throw an
exception.  But

  step withoutEnsure =>
    using { mkdir "/net" }
    ;

seems somewhat useless to me.  Considering the fact that other blocks
may
exist (sanity/rollback/etc.), perhaps a missing C<ensure> should be
treated specially so it fails before C<using> and succeeds after.

IMO lack of them is programmer error, and should throw an exeption.
What is the use of using your framework but to use the ensure and using
directives and get those benefits? Otherwise are you not just adding
several levels of indirection for a subroutine call?

I agree that ensure should always be there. using not being there ... *shrugs* - not so big a deal.

I also have a feature suggestion for you, as this is something I
recently ran into. How about the ability to have a timeout on the
block? I recently had a problem where a cron job was hanging for about
8 hours because a very odd condition occurred which caused a subprocess
to require user input. The result was that everything seemed to report
success, but the process was not yet complete (and so couldn't fail and
tell me what was wrong). Not until I checked the output of top did I
see what was wrong. No granted it was my own stupid fault (I am mostly
a programmer, and I am a mediocre sys-admin at best), but a timeout on
that particular block of code would have been nice.

I like the idea of a "no_longer_than" with a prototype of ($@) that takes a number of seconds to run. Alternatively, you could use a format of /\d+[A-Za-z]?/ and allow things like 30m, 2d, 12h, 3600s, etc.

********

NOTE: One thing that you need to be aware of is the potential for
memory leaks and other problems using the & prototype. See
http://www.perlmonks.org/?node_id=278900 for more info.

********

_______________________________________________
sw-design mailing list
[EMAIL PROTECTED]
http://metaperl.com/cgi-bin/mailman/listinfo/sw-design



_______________________________________________
sw-design mailing list
[EMAIL PROTECTED]
http://metaperl.com/cgi-bin/mailman/listinfo/sw-design

Reply via email to