FAQ
I'm iworking on a patch for Perl 5 that implements the Perl 6 closure
traits (ENTER/LEAVE/...) as special blocks. There are several details
that aren't clear to me from either S04 or the spec tests; I apologize
if these have been discussed before, as I haven't been following p6l.
I'm also not subscribed, so if people could keep me in the CC that would
be appreciated.

- Presumably when an exception is thrown through a block, the LEAVE and
POST queues are called (in that order). What if a PRE block fails: is
the POST queue on the same block called? (Do you have to satisfy your
post-conditions even if your pre-conditions failed?)

- If a POST block is called as a result of a thrown exception, and it
fails, which exception 'wins'?

- Presumably if an ENTER block dies, the rest of that ENTER queue is
abandoned. Does that also apply to the LEAVE queue? What should

{
LEAVE { say "leave1" }
LEAVE { say "leave2"; die "foo"; }
}

print? Similarly POST: once one post-condition has failed, are
subsequent post-conditions checked?

- Can a try block catch an exception thrown from its own ENTER or LEAVE
queue? For example in this case:

try {

try {
ENTER { die "foo" }
CATCH { default { say "caught inside" } }
}

CATCH { default { say "caught outside" } }
}

which CATCH block gets the exception? What about PRE/POST: can you
CATCH failure of your own pre-/post-conditions?

- Does it make any difference in any of the above if 'die' is replaced
by 'exit'?

Ben

Search Discussions

  • Moritz Lenz at Jul 26, 2009 at 12:43 pm

    Ben Morrow wrote:
    I'm iworking on a patch for Perl 5 that implements the Perl 6 closure
    traits (ENTER/LEAVE/...) as special blocks. There are several details
    that aren't clear to me from either S04 or the spec tests; I apologize
    if these have been discussed before, as I haven't been following p6l.

    No need to apologize; such things should be clear from reading the spec.

    Note that my answers are in no way authoritative, just proposals on how
    to handle it (and maybe starting point of useful discussions).
    I'm also not subscribed, so if people could keep me in the CC that would
    be appreciated.

    - Presumably when an exception is thrown through a block, the LEAVE and
    POST queues are called (in that order).
    POST was inspired from the Design By Contract department, and are meant
    to execute assertions on the result. If you leave a block through an
    exception you don't have a result, so I don't think running a POST block
    makes sense.
    I'm not sure about running LEAVE blocks either, because that's what
    CATCH blocks are for.
    What if a PRE block fails: is
    the POST queue on the same block called? (Do you have to satisfy your
    post-conditions even if your pre-conditions failed?)
    I'd say that if a PRE block fails, nothing else is run (neither LEAVE
    nor POST nor ...)
    - If a POST block is called as a result of a thrown exception, and it
    fails, which exception 'wins'?
    Question obsoleted by previous answer ;-)
    - Presumably if an ENTER block dies, the rest of that ENTER queue is
    abandoned. Does that also apply to the LEAVE queue? What should

    {
    LEAVE { say "leave1" }
    LEAVE { say "leave2"; die "foo"; }
    }

    print? Similarly POST: once one post-condition has failed, are
    subsequent post-conditions checked?
    - Can a try block catch an exception thrown from its own ENTER or LEAVE
    queue? Yes.
    For example in this case:

    try {

    try {
    ENTER { die "foo" }
    CATCH { default { say "caught inside" } }
    }

    CATCH { default { say "caught outside" } }
    }

    which CATCH block gets the exception? What about PRE/POST: can you
    CATCH failure of your own pre-/post-conditions?

    - Does it make any difference in any of the above if 'die' is replaced
    by 'exit'?
    No idea, really.

    HTH,
    Moritz
  • Ben Morrow at Jul 27, 2009 at 4:27 pm

    Moritz Lenz wrote:
    Ben Morrow wrote:
    - Presumably when an exception is thrown through a block, the LEAVE and
    POST queues are called (in that order).
    POST was inspired from the Design By Contract department, and are meant
    to execute assertions on the result. If you leave a block through an
    exception you don't have a result, so I don't think running a POST block
    makes sense.
    OK, if POST is only for asserting on the return value that would make
    sense. But I thought POST was also supposed to be able to assert that
    global state had been left as it should, in which case it should be run
    even on exceptional exit? I'm not sure how any given POST block is
    supposed to distinguish between an ordinary undef return and an
    exception, though, to avoid checking the return value. Some sort of
    guarantee that $! is undef in a POST block unless an exception is
    currently being thrown might be helpful, but I'm not sure how that
    interacts with the Perl 6 exception model as a whole.
    I'm not sure about running LEAVE blocks either, because that's what
    CATCH blocks are for.
    LEAVE blocks I am certain *should* be run, no matter how the block is
    exitted (well, unless a PRE fails: see below). They are equivalent to
    'finally' blocks in other languages, and AIUI they are for cleanup:
    closing files, tearing down database connections and the like.
    What if a PRE block fails: is
    the POST queue on the same block called? (Do you have to satisfy your
    post-conditions even if your pre-conditions failed?)
    I'd say that if a PRE block fails, nothing else is run (neither LEAVE
    nor POST nor ...)
    I agree that none of ENTER, LEAVE or the main body of the block should
    be run. However, if a POST block is asserting, say, that a global holds
    a valid value, shouldn't that still be checked even if your
    preconditions failed? I admit I haven't read much about DBC.
    - If a POST block is called as a result of a thrown exception, and it
    fails, which exception 'wins'?
    Question obsoleted by previous answer ;-)
    ...maybe :).
    - Can a try block catch an exception thrown from its own ENTER or LEAVE
    queue?
    Yes.
    OK. What about PRE/POST? It seems wrong somehow to be able to catch
    failure of your own pre-/post-conditions: they are meant for the caller
    to catch. Does that seem right?

    Ben
  • Moritz Lenz at Jul 27, 2009 at 4:46 pm

    Ben Morrow wrote:
    Moritz Lenz wrote:
    Ben Morrow wrote:
    - Presumably when an exception is thrown through a block, the LEAVE and
    POST queues are called (in that order).
    POST was inspired from the Design By Contract department, and are meant
    to execute assertions on the result. If you leave a block through an
    exception you don't have a result, so I don't think running a POST block
    makes sense.
    OK, if POST is only for asserting on the return value that would make
    sense. But I thought POST was also supposed to be able to assert that
    global state had been left as it should, in which case it should be run
    even on exceptional exit?
    I never thought of that, because in the only other DBC-enabled language
    that I've used (Eiffel) there are other assertions types for that (iirc
    they are called "class invariants", but I'm not entirely sure) which are
    run after every method call from the outside of the class, or something
    along these lines.

    I haven't seen such a thing in the spec in Perl 6, so either we invent
    such a thing, or pick up your position (always run POST)
    I'm not sure how any given POST block is
    supposed to distinguish between an ordinary undef return and an
    exception, though, to avoid checking the return value. Some sort of
    guarantee that $! is undef in a POST block unless an exception is
    currently being thrown might be helpful, but I'm not sure how that
    interacts with the Perl 6 exception model as a whole.
    Same here.
    I'm not sure about running LEAVE blocks either, because that's what
    CATCH blocks are for.
    LEAVE blocks I am certain *should* be run, no matter how the block is
    exitted (well, unless a PRE fails: see below). They are equivalent to
    'finally' blocks in other languages, and AIUI they are for cleanup:
    closing files, tearing down database connections and the like.
    You're right here; it's the KEEP block that is only executed on normal exit.
    What if a PRE block fails: is
    the POST queue on the same block called? (Do you have to satisfy your
    post-conditions even if your pre-conditions failed?)
    I'd say that if a PRE block fails, nothing else is run (neither LEAVE
    nor POST nor ...)
    I agree that none of ENTER, LEAVE or the main body of the block should
    be run. However, if a POST block is asserting, say, that a global holds
    a valid value, shouldn't that still be checked even if your
    preconditions failed? I admit I haven't read much about DBC.
    Same as for the first question.
    - If a POST block is called as a result of a thrown exception, and it
    fails, which exception 'wins'?
    Question obsoleted by previous answer ;-)
    ...maybe :).
    If not: $! is an aggregate of all exceptions thrown so far, so whichever
    way we go, we don't lose any information. I fear that doesn't help you
    very much, though, because it's different in Perl 5.

    I personally prefer to know about the first exception, for example I
    find it more informative that an open() fails than that a subsequent
    print() to that file failed.
    - Can a try block catch an exception thrown from its own ENTER or LEAVE
    queue?
    Yes.
    OK. What about PRE/POST? It seems wrong somehow to be able to catch
    failure of your own pre-/post-conditions: they are meant for the caller
    to catch. Does that seem right?
    Yes.
    (Actually they are not really meant to be caught, because they always
    reveal programming errors, but I guess sometimes you still can't avoid it).

    I just fear that I haven't contributed much clarity at all :/

    Cheers,
    Moritz
  • Ben Morrow at Aug 11, 2009 at 8:21 am
    Sorry for the delay in replying, but I was busy with other things and I
    wanted to give other people a chance to reply. Since noone has, might it
    be possible to get the attached patches committed? I'm not familiar with
    the protocol for such things so, again, I'm sorry if I've got it wrong.

    Ben

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupperl6-language @
categoriesperl
postedJul 25, '09 at 8:39p
activeAug 11, '09 at 8:21a
posts5
users2
websiteperl6.org

2 users in discussion

Ben Morrow: 3 posts Moritz Lenz: 2 posts

People

Translate

site design / logo © 2021 Grokbase