Trey,
Welcome to the list :)
On Nov 22, 2004, at 10:12 PM, Trey Harris wrote:
Greetings,
I joined this list after my module was first mentioned here. I'm amazed,
honestly, that folks are actually looking at it, rating it on CPAN,
posting bug reports, and asking me questions about it (only some of which
are RTFM or feature requests ;-) -- I thought it was just this kooky idea
that might only match the way I think about scripting. Apparently not!
It's a very cool module. I know myself I have hacked together scripts which manually do most of the stuff your module does, but it never occurred to me to put it into a framework like you have done. Nice job really, I know I am looking forward to playing with it on when next I have the chance.
Anyway, as to the question of preconditions--it seems to me that the right
way to implement them is as a new step block, and either "presuming" or
"assuming" is the right word. So:
step withPrecondition => ensure { -d '/net/scratch' } presuming { -d '/net' } using { mkdir "/net/scratch" } ;
I assume that C<presuming> would not be checked if the C<ensure> block succeeded, but I'm willing to hear arguments to the contrary.
In your code docs you have the following bit of pseudo code:
unless (ENSURE) {
USING;
die unless ENSURE;
}From that I am assuming that an ensure statement is something you want to be true *after* your statement is run, but *not* before it (and if it is true before, then the statement is not needed). I think the pre-condition (at least from my POV on the subject) would work something like this:
die unless PRECONDITION;
unless (ENSURE) {
USING;
die unless ENSURE;
}However, there are times when it might make sense for that pre-condition block to be post-ensure, if it were only guarding the using statement, but I could imagine cases when it would make sense to guard the ensure statement as well. Maybe you need 2 types of pre-conditions? One for guarding ensure and another for guarding the entire step. Although maybe something like this would work.
presuming {
-e '/net'
} step MyStuff =>
ensure { -d '/net/scratch' }
presuming { -d '/net' }
using { mkdir 'net/scratch' }
;Then your presuming function would assume that its first argument is the guard clause, and its second argument is the action it is guarding (which IMO should be either C<step> or C<using>). This also make presuming into a more general purpose clause-guard tool, which may come in handy later on.
Does that make sense?
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?
In that case
step withPre => presuming { -d "/net" } using { mkdir "/net/scratch" } ;
Would run equivalently to
{ die unless -d '/net'; mkdir "/net/scratch"; }
I still don't have the ALWAYS variant allowed for here, though. What I need is a postcondition block. What I'm blocked on is a name that is sufficiently declarative--i.e.,
step withPost => using { mkdir "/net/scratch" } WHAT? { -d "/net/scratch" } ;
That screams for C<ensure>, but that word's already taken.
The post-condition seems silly to me since your ensure kind of does that already. Sure it is not a pure post-condition since it has implications for the "pre" state, but I think that it is okay.
IMO I would make ensure and using required, this eliminates the need for post-condtions for now. Then as people start to use your module it will come out if there is a need for post-conditions and in what cases those needs arise. At that point, you can figure it out and you will have much more to go on.
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.
Anyway, again, welcome to the list, and very cool module.
Steve
_______________________________________________ sw-design mailing list [EMAIL PROTECTED] http://metaperl.com/cgi-bin/mailman/listinfo/sw-design
