FAQ
Is there any reason why one is not allowed to throw an exception in the
destructor of a class?
I mean, it makes sense, considering this is not always the final step of code,
and it is usually used for finalising things, and it would be a good idea to
know if anything goes wrong at that stage.
Otherwise is there any compromise one can use to "emulate" this feature?

Daine Mamacos.

--
random signature

Search Discussions

  • Marcus Boerger at Dec 16, 2005 at 7:36 pm
    Hello Daine,

    marcus@zaphod /usr/src/PHP_5_1 $ php -r 'class A{function __destruct(){throw new Exception("A");}} new A;'
    make: `sapi/cli/php' is up to date.

    Fatal error: Uncaught exception 'Exception' with message 'A' in Command line code:1
    Stack trace:
    #0 Command line code(1): A::__destruct()
    #1 {main}
    thrown in Command line code on line 1

    As the code above clearly show, exceptions can be thrown.

    marcus

    Friday, December 16, 2005, 3:17:54 PM, you wrote:
    Is there any reason why one is not allowed to throw an exception in the
    destructor of a class?
    I mean, it makes sense, considering this is not always the final step of code,
    and it is usually used for finalising things, and it would be a good idea to
    know if anything goes wrong at that stage.
    Otherwise is there any compromise one can use to "emulate" this feature?
    Daine Mamacos.
    --
    random signature



    Best regards,
    Marcus
  • Daine Mamacos at Dec 20, 2005 at 1:58 pm
    I'm not trying to argue here,
    I just asked a question, and you've managed to contradict your first post.

    I just asked why this is the case, and if it is, is there any way I can work
    WITH this functionality.

    Your last post also indicates, that because the destructors are only called
    after script termination, the scope of an object is global, always.
    Is this true?

    Also, I've called fwrite in a destructor before, so clearly not all IO is
    terminated before the destructor is called.
    When you refer to output facility, what are you talking about?

    Many thanks
    Daine Mamacos.


    On Mon, 19 Dec 2005 20:16:07 +0100, Marcus Boerger wrote
    Hello Daine,

    you still don't get it. Your problem is the way php works. You
    cannot put any output functionality in destructors because they are
    called *after* your scipt is being terminted (to be precise after
    the output facility has been shutdown on script termination).

    This is btw a question the general php list.

    marcus

    Monday, December 19, 2005, 11:07:53 AM, you wrote:
    While you're example works, mine doesn't, it has to do with the class
    assignment. If you actually bother to do anything with the class, it
    doesn't work.
    $ php -r 'class blah { function __destruct() { throw new Exception("exception
    thrown"); } } $blah = new blah();'
    give that a try and see what happens
    (;
    also http://bugs.php.net/bug.php?id=33598 clearly states that they cannoy be
    thrown in the destructor.
    Errrr... *shrug*
    On Fri, 16 Dec 2005 20:38:20 +0100, Marcus Boerger wrote
    Hello Daine,

    marcus@zaphod /usr/src/PHP_5_1 $ php -r 'class A{function
    __destruct(){throw new Exception("A");}} new A;' make:
    `sapi/cli/php' is up to date.

    Fatal error: Uncaught exception 'Exception' with message 'A' in
    Command line code:1 Stack trace:
    #0 Command line code(1): A::__destruct()
    #1 {main}
    thrown in Command line code on line 1

    As the code above clearly show, exceptions can be thrown.

    marcus

    Friday, December 16, 2005, 3:17:54 PM, you wrote:
    Is there any reason why one is not allowed to throw an exception in the
    destructor of a class?
    I mean, it makes sense, considering this is not always the final step
    of code,
    and it is usually used for finalising things, and it would be a good
    idea to
    know if anything goes wrong at that stage.
    Otherwise is there any compromise one can use to "emulate" this feature?
    Daine Mamacos.
    --
    random signature
    Best regards,
    Marcus

    --
    PHP Internals - PHP Runtime Development Mailing List
    To unsubscribe, visit: http://www.php.net/unsub.php
    --
    random signature
    --
    Best regards,
    Marcus mailto:mail@marcus-boerger.de

    --
    random signature
  • Alan Pinstein at Dec 20, 2005 at 4:38 pm

    Your last post also indicates, that because the destructors are
    only called
    after script termination, the scope of an object is global, always.
    Is this true?
    This isn't true, at least empirically. Destructors are called when
    the GC frees the object.

    For many objects, this is at script termination. But if you null out
    the ref to an object, it will occur immediately.

    $a = new A();
    $a = null; // destructor called just after this line

    I am not certain that this should be considered *predictable*
    behavior, as the behavior of the GC is not well/publicly documented
    to my knowledge, and thus this is a reasonable question for the
    internals list.

    Personally I would like to see more documentation of how GC works so
    that we as developers can depend on it a little better for OO cleanup
    activities. I have another thread going that still remains unanswered
    about how to prevent circular references to objects that deadlock the
    GC.

    Alan
    Also, I've called fwrite in a destructor before, so clearly not all
    IO is
    terminated before the destructor is called.
    When you refer to output facility, what are you talking about?

    Many thanks
    Daine Mamacos.


    On Mon, 19 Dec 2005 20:16:07 +0100, Marcus Boerger wrote
    Hello Daine,

    you still don't get it. Your problem is the way php works. You
    cannot put any output functionality in destructors because they are
    called *after* your scipt is being terminted (to be precise after
    the output facility has been shutdown on script termination).

    This is btw a question the general php list.

    marcus

    Monday, December 19, 2005, 11:07:53 AM, you wrote:
    While you're example works, mine doesn't, it has to do with the
    class
    assignment. If you actually bother to do anything with the class, it
    doesn't work.
    $ php -r 'class blah { function __destruct() { throw new Exception
    ("exception
    thrown"); } } $blah = new blah();'
    give that a try and see what happens
    (;
    also http://bugs.php.net/bug.php?id=33598 clearly states that
    they cannoy be
    thrown in the destructor.
    Errrr... *shrug*
    On Fri, 16 Dec 2005 20:38:20 +0100, Marcus Boerger wrote
    Hello Daine,

    marcus@zaphod /usr/src/PHP_5_1 $ php -r 'class A{function
    __destruct(){throw new Exception("A");}} new A;' make:
    `sapi/cli/php' is up to date.

    Fatal error: Uncaught exception 'Exception' with message 'A' in
    Command line code:1 Stack trace:
    #0 Command line code(1): A::__destruct()
    #1 {main}
    thrown in Command line code on line 1

    As the code above clearly show, exceptions can be thrown.

    marcus

    Friday, December 16, 2005, 3:17:54 PM, you wrote:
    Is there any reason why one is not allowed to throw an
    exception in the
    destructor of a class?
    I mean, it makes sense, considering this is not always the
    final step
    of code,
    and it is usually used for finalising things, and it would be a
    good
    idea to
    know if anything goes wrong at that stage.
    Otherwise is there any compromise one can use to "emulate" this
    feature?
    Daine Mamacos.
    --
    random signature
    Best regards,
    Marcus

    --
    PHP Internals - PHP Runtime Development Mailing List
    To unsubscribe, visit: http://www.php.net/unsub.php
    --
    random signature
    --
    Best regards,
    Marcus mailto:mail@marcus-boerger.de

    --
    random signature

    --
    PHP Internals - PHP Runtime Development Mailing List
    To unsubscribe, visit: http://www.php.net/unsub.php
  • Jochem Maas at Dec 20, 2005 at 4:59 pm

    Alan Pinstein wrote:
    Your last post also indicates, that because the destructors are only
    called
    after script termination, the scope of an object is global, always.
    Is this true?

    This isn't true, at least empirically. Destructors are called when the
    GC frees the object.

    For many objects, this is at script termination. But if you null out
    the ref to an object, it will occur immediately.

    $a = new A();
    $a = null; // destructor called just after this line

    I am not certain that this should be considered *predictable* behavior,
    as the behavior of the GC is not well/publicly documented to my
    knowledge, and thus this is a reasonable question for the internals list.

    Personally I would like to see more documentation of how GC works so
    that we as developers can depend on it a little better for OO cleanup
    activities. I have another thread going that still remains unanswered
    about how to prevent circular references to objects that deadlock the GC.
    I feel the usefulness of the dtors is undermined even more by the
    'chiken/egg' problem regarding which comes first 'shutdown' or 'running the dtors';

    I don't claim to have a solution or even understand the problem fully but it
    does seem to me that for most of the things an average developer would think of
    using object dtors for, the mechanism is unusable; and from what I understand the
    'chicken/egg' problem I mentioned has been an ongoing PITA for devs!
    (IIRC Wez mentioned the to-ing and fro-ing regarding this not so long ago)

    Phorce be with you. (excuse me, but I have just had my annual starwars fix :-)
    Alan
  • Daine Mamacos at Dec 20, 2005 at 5:23 pm
    I agree completely...
    I think the GC should be better documented.
    I also would like someone to tell me why exceptions cannot be called in the
    destructor? Since they can't, this means the reliability of a destructor is
    uncontrolled and nothing can be done to see if this completes successfully.

    This in some way or another, renders them completely useless if you require
    them to complete an operation and at least have the peace of mind that you
    will be able to deal with errors rather than the application throwing a fatal
    error.


    On Tue, 20 Dec 2005 11:38:34 -0500, Alan Pinstein wrote
    Your last post also indicates, that because the destructors are
    only called
    after script termination, the scope of an object is global, always.
    Is this true?
    This isn't true, at least empirically. Destructors are called when
    the GC frees the object.

    For many objects, this is at script termination. But if you null out
    the ref to an object, it will occur immediately.

    $a = new A();
    $a = null; // destructor called just after this line

    I am not certain that this should be considered *predictable*
    behavior, as the behavior of the GC is not well/publicly documented
    to my knowledge, and thus this is a reasonable question for the
    internals list.

    Personally I would like to see more documentation of how GC works so
    that we as developers can depend on it a little better for OO
    cleanup activities. I have another thread going that still remains
    unanswered about how to prevent circular references to objects that
    deadlock the GC.

    Alan
    Also, I've called fwrite in a destructor before, so clearly not all
    IO is
    terminated before the destructor is called.
    When you refer to output facility, what are you talking about?

    Many thanks
    Daine Mamacos.


    On Mon, 19 Dec 2005 20:16:07 +0100, Marcus Boerger wrote
    Hello Daine,

    you still don't get it. Your problem is the way php works. You
    cannot put any output functionality in destructors because they are
    called *after* your scipt is being terminted (to be precise after
    the output facility has been shutdown on script termination).

    This is btw a question the general php list.

    marcus

    Monday, December 19, 2005, 11:07:53 AM, you wrote:
    While you're example works, mine doesn't, it has to do with the
    class
    assignment. If you actually bother to do anything with the class, it
    doesn't work.
    $ php -r 'class blah { function __destruct() { throw new Exception
    ("exception
    thrown"); } } $blah = new blah();'
    give that a try and see what happens
    (;
    also http://bugs.php.net/bug.php?id=33598 clearly states that
    they cannoy be
    thrown in the destructor.
    Errrr... *shrug*
    On Fri, 16 Dec 2005 20:38:20 +0100, Marcus Boerger wrote
    Hello Daine,

    marcus@zaphod /usr/src/PHP_5_1 $ php -r 'class A{function
    __destruct(){throw new Exception("A");}} new A;' make:
    `sapi/cli/php' is up to date.

    Fatal error: Uncaught exception 'Exception' with message 'A' in
    Command line code:1 Stack trace:
    #0 Command line code(1): A::__destruct()
    #1 {main}
    thrown in Command line code on line 1

    As the code above clearly show, exceptions can be thrown.

    marcus

    Friday, December 16, 2005, 3:17:54 PM, you wrote:
    Is there any reason why one is not allowed to throw an
    exception in the
    destructor of a class?
    I mean, it makes sense, considering this is not always the
    final step
    of code,
    and it is usually used for finalising things, and it would be a
    good
    idea to
    know if anything goes wrong at that stage.
    Otherwise is there any compromise one can use to "emulate" this
    feature?
    Daine Mamacos.
    --
    random signature
    Best regards,
    Marcus

    --
    PHP Internals - PHP Runtime Development Mailing List
    To unsubscribe, visit: http://www.php.net/unsub.php
    --
    random signature
    --
    Best regards,
    Marcus mailto:mail@marcus-boerger.de

    --
    random signature

    --
    PHP Internals - PHP Runtime Development Mailing List
    To unsubscribe, visit: http://www.php.net/unsub.php
    --
    PHP Internals - PHP Runtime Development Mailing List
    To unsubscribe, visit: http://www.php.net/unsub.php

    --
    random signature
  • Marcus Boerger at Dec 20, 2005 at 8:25 pm
    Hello Daine,


    a) i didn't contradict myself - you obviously didn't really follow
    what i wrote

    b) you can force calling the destructor by using unset() or = null;
    but only if reference count is 1.
    c) exceptions are 'thrown' not called, maybe you didn't use throw new
    exception here or you were just writing a bit weired?
    d) as said already several times (not only to you) exceptions *can*
    be thrown in destructors

    e) this doesn't belong in internals@

    regards
    marcus

    Tuesday, December 20, 2005, 6:22:31 PM, you wrote:
    I agree completely...
    I think the GC should be better documented.
    I also would like someone to tell me why exceptions cannot be called in the
    destructor? Since they can't, this means the reliability of a destructor is
    uncontrolled and nothing can be done to see if this completes successfully.
    This in some way or another, renders them completely useless if you require
    them to complete an operation and at least have the peace of mind that you
    will be able to deal with errors rather than the application throwing a fatal
    error.
    On Tue, 20 Dec 2005 11:38:34 -0500, Alan Pinstein wrote
    Your last post also indicates, that because the destructors are
    only called
    after script termination, the scope of an object is global, always.
    Is this true?
    This isn't true, at least empirically. Destructors are called when
    the GC frees the object.

    For many objects, this is at script termination. But if you null out
    the ref to an object, it will occur immediately.

    $a = new A();
    $a = null; // destructor called just after this line

    I am not certain that this should be considered *predictable*
    behavior, as the behavior of the GC is not well/publicly documented
    to my knowledge, and thus this is a reasonable question for the
    internals list.

    Personally I would like to see more documentation of how GC works so
    that we as developers can depend on it a little better for OO
    cleanup activities. I have another thread going that still remains
    unanswered about how to prevent circular references to objects that
    deadlock the GC.

    Alan
    Also, I've called fwrite in a destructor before, so clearly not all
    IO is
    terminated before the destructor is called.
    When you refer to output facility, what are you talking about?

    Many thanks
    Daine Mamacos.


    On Mon, 19 Dec 2005 20:16:07 +0100, Marcus Boerger wrote
    Hello Daine,

    you still don't get it. Your problem is the way php works. You
    cannot put any output functionality in destructors because they are
    called *after* your scipt is being terminted (to be precise after
    the output facility has been shutdown on script termination).

    This is btw a question the general php list.

    marcus

    Monday, December 19, 2005, 11:07:53 AM, you wrote:
    While you're example works, mine doesn't, it has to do with the
    class
    assignment. If you actually bother to do anything with the class, it
    doesn't work.
    $ php -r 'class blah { function __destruct() { throw new Exception
    ("exception
    thrown"); } } $blah = new blah();'
    give that a try and see what happens
    (;
    also http://bugs.php.net/bug.php?id=33598 clearly states that
    they cannoy be
    thrown in the destructor.
    Errrr... *shrug*
    On Fri, 16 Dec 2005 20:38:20 +0100, Marcus Boerger wrote
    Hello Daine,

    marcus@zaphod /usr/src/PHP_5_1 $ php -r 'class A{function
    __destruct(){throw new Exception("A");}} new A;' make:
    `sapi/cli/php' is up to date.

    Fatal error: Uncaught exception 'Exception' with message 'A' in
    Command line code:1 Stack trace:
    #0 Command line code(1): A::__destruct()
    #1 {main}
    thrown in Command line code on line 1

    As the code above clearly show, exceptions can be thrown.

    marcus

    Friday, December 16, 2005, 3:17:54 PM, you wrote:
    Is there any reason why one is not allowed to throw an
    exception in the
    destructor of a class?
    I mean, it makes sense, considering this is not always the
    final step
    of code,
    and it is usually used for finalising things, and it would be a
    good
    idea to
    know if anything goes wrong at that stage.
    Otherwise is there any compromise one can use to "emulate" this
    feature?
    Daine Mamacos.
    --
    random signature
    Best regards,
    Marcus

    --
    PHP Internals - PHP Runtime Development Mailing List
    To unsubscribe, visit: http://www.php.net/unsub.php
    --
    random signature
    --
    Best regards,
    Marcus mailto:mail@marcus-boerger.de

    --
    random signature

    --
    PHP Internals - PHP Runtime Development Mailing List
    To unsubscribe, visit: http://www.php.net/unsub.php
    --
    PHP Internals - PHP Runtime Development Mailing List
    To unsubscribe, visit: http://www.php.net/unsub.php
    --
    random signature



    Best regards,
    Marcus
  • Marcus Boerger at Dec 20, 2005 at 11:51 pm
    Hello Daine,
    a) i didn't contradict myself - you obviously didn't really follow
    what i wrote
    b) you can force calling the destructor by using unset() or = null;
    but only if reference count is 1.
    c) exceptions are 'thrown' not called, maybe you didn't use throw new
    exception here or you were just writing a bit weired?
    d) as said already several times (not only to you) exceptions *can*
    be thrown in destructors
    e) this doesn't belong in internals@
    to not forget to mention: the only thing you cannot do is throwing an
    exception while an exception is already pending.

    regards
    marcus
  • Daine Mamacos at Dec 21, 2005 at 12:14 am
    Marcus,
    I'm not trying to argue with you, I'm just after some help.
    You are confusing me somewhat.
    The php manual clearly states:
    "Note: Attempting to throw an exception from a destructor causes a fatal error."
    I'm somewhat convinced that you cannot throw an exception from a destructor,
    well you can, but it gets you nowhere.

    What does forcing the call of a destructor have to do with this conversation?

    If you can think of a way of working around this, that would be greatly appreciated.

    Anyway,
    Thanks
    Daine Mamacos

    On Tue, 20 Dec 2005 21:27:30 +0100, Marcus Boerger wrote
    Hello Daine,

    a) i didn't contradict myself - you obviously didn't really follow
    what i wrote

    b) you can force calling the destructor by using unset() or = null;
    but only if reference count is 1.
    c) exceptions are 'thrown' not called, maybe you didn't use throw new
    exception here or you were just writing a bit weired?
    d) as said already several times (not only to you) exceptions *can*
    be thrown in destructors

    e) this doesn't belong in internals@

    regards
    marcus

    Tuesday, December 20, 2005, 6:22:31 PM, you wrote:
    I agree completely...
    I think the GC should be better documented.
    I also would like someone to tell me why exceptions cannot be called in the
    destructor? Since they can't, this means the reliability of a destructor is
    uncontrolled and nothing can be done to see if this completes successfully.
    This in some way or another, renders them completely useless if you require
    them to complete an operation and at least have the peace of mind that you
    will be able to deal with errors rather than the application throwing a fatal
    error.
    On Tue, 20 Dec 2005 11:38:34 -0500, Alan Pinstein wrote
    Your last post also indicates, that because the destructors are
    only called
    after script termination, the scope of an object is global, always.
    Is this true?
    This isn't true, at least empirically. Destructors are called when
    the GC frees the object.

    For many objects, this is at script termination. But if you null out
    the ref to an object, it will occur immediately.

    $a = new A();
    $a = null; // destructor called just after this line

    I am not certain that this should be considered *predictable*
    behavior, as the behavior of the GC is not well/publicly documented
    to my knowledge, and thus this is a reasonable question for the
    internals list.

    Personally I would like to see more documentation of how GC works so
    that we as developers can depend on it a little better for OO
    cleanup activities. I have another thread going that still remains
    unanswered about how to prevent circular references to objects that
    deadlock the GC.

    Alan
    Also, I've called fwrite in a destructor before, so clearly not all
    IO is
    terminated before the destructor is called.
    When you refer to output facility, what are you talking about?

    Many thanks
    Daine Mamacos.


    On Mon, 19 Dec 2005 20:16:07 +0100, Marcus Boerger wrote
    Hello Daine,

    you still don't get it. Your problem is the way php works. You
    cannot put any output functionality in destructors because they are
    called *after* your scipt is being terminted (to be precise after
    the output facility has been shutdown on script termination).

    This is btw a question the general php list.

    marcus

    Monday, December 19, 2005, 11:07:53 AM, you wrote:
    While you're example works, mine doesn't, it has to do with the
    class
    assignment. If you actually bother to do anything with the class, it
    doesn't work.
    $ php -r 'class blah { function __destruct() { throw new Exception
    ("exception
    thrown"); } } $blah = new blah();'
    give that a try and see what happens
    (;
    also http://bugs.php.net/bug.php?id=33598 clearly states that
    they cannoy be
    thrown in the destructor.
    Errrr... *shrug*
    On Fri, 16 Dec 2005 20:38:20 +0100, Marcus Boerger wrote
    Hello Daine,

    marcus@zaphod /usr/src/PHP_5_1 $ php -r 'class A{function
    __destruct(){throw new Exception("A");}} new A;' make:
    `sapi/cli/php' is up to date.

    Fatal error: Uncaught exception 'Exception' with message 'A' in
    Command line code:1 Stack trace:
    #0 Command line code(1): A::__destruct()
    #1 {main}
    thrown in Command line code on line 1

    As the code above clearly show, exceptions can be thrown.

    marcus

    Friday, December 16, 2005, 3:17:54 PM, you wrote:
    Is there any reason why one is not allowed to throw an
    exception in the
    destructor of a class?
    I mean, it makes sense, considering this is not always the
    final step
    of code,
    and it is usually used for finalising things, and it would be a
    good
    idea to
    know if anything goes wrong at that stage.
    Otherwise is there any compromise one can use to "emulate" this
    feature?
    Daine Mamacos.
    --
    random signature
    Best regards,
    Marcus

    --
    PHP Internals - PHP Runtime Development Mailing List
    To unsubscribe, visit: http://www.php.net/unsub.php
    --
    random signature
    --
    Best regards,
    Marcus mailto:mail@marcus-boerger.de

    --
    random signature

    --
    PHP Internals - PHP Runtime Development Mailing List
    To unsubscribe, visit: http://www.php.net/unsub.php
    --
    PHP Internals - PHP Runtime Development Mailing List
    To unsubscribe, visit: http://www.php.net/unsub.php
    --
    random signature
    Best regards,
    Marcus

    --
    random signature
  • Daine Mamacos at Dec 21, 2005 at 12:21 am
    I see where all this is going.
    As long as the destructor is not called as part of the cleanup code, it
    works fine.
    Is that assumption correct?


    On Wed, 21 Dec 2005 00:14:15 +0000, Daine Mamacos wrote
    Marcus,
    I'm not trying to argue with you, I'm just after some help.
    You are confusing me somewhat.
    The php manual clearly states:
    "Note: Attempting to throw an exception from a destructor causes a
    fatal error." I'm somewhat convinced that you cannot throw an
    exception from a destructor, well you can, but it gets you nowhere.

    What does forcing the call of a destructor have to do with this conversation?

    If you can think of a way of working around this, that would be
    greatly appreciated.

    Anyway,
    Thanks
    Daine Mamacos

    On Tue, 20 Dec 2005 21:27:30 +0100, Marcus Boerger wrote
    Hello Daine,

    a) i didn't contradict myself - you obviously didn't really follow
    what i wrote

    b) you can force calling the destructor by using unset() or = null;
    but only if reference count is 1.
    c) exceptions are 'thrown' not called, maybe you didn't use throw new
    exception here or you were just writing a bit weired?
    d) as said already several times (not only to you) exceptions *can*
    be thrown in destructors

    e) this doesn't belong in internals@

    regards
    marcus

    Tuesday, December 20, 2005, 6:22:31 PM, you wrote:
    I agree completely...
    I think the GC should be better documented.
    I also would like someone to tell me why exceptions cannot be called in the
    destructor? Since they can't, this means the reliability of a destructor is
    uncontrolled and nothing can be done to see if this completes successfully.
    This in some way or another, renders them completely useless if you require
    them to complete an operation and at least have the peace of mind that you
    will be able to deal with errors rather than the application throwing a fatal
    error.
    On Tue, 20 Dec 2005 11:38:34 -0500, Alan Pinstein wrote
    Your last post also indicates, that because the destructors are
    only called
    after script termination, the scope of an object is global, always.
    Is this true?
    This isn't true, at least empirically. Destructors are called when
    the GC frees the object.

    For many objects, this is at script termination. But if you null out
    the ref to an object, it will occur immediately.

    $a = new A();
    $a = null; // destructor called just after this line

    I am not certain that this should be considered *predictable*
    behavior, as the behavior of the GC is not well/publicly documented
    to my knowledge, and thus this is a reasonable question for the
    internals list.

    Personally I would like to see more documentation of how GC works so
    that we as developers can depend on it a little better for OO
    cleanup activities. I have another thread going that still remains
    unanswered about how to prevent circular references to objects that
    deadlock the GC.

    Alan
    Also, I've called fwrite in a destructor before, so clearly not all
    IO is
    terminated before the destructor is called.
    When you refer to output facility, what are you talking about?

    Many thanks
    Daine Mamacos.


    On Mon, 19 Dec 2005 20:16:07 +0100, Marcus Boerger wrote
    Hello Daine,

    you still don't get it. Your problem is the way php works. You
    cannot put any output functionality in destructors because they are
    called *after* your scipt is being terminted (to be precise after
    the output facility has been shutdown on script termination).

    This is btw a question the general php list.

    marcus

    Monday, December 19, 2005, 11:07:53 AM, you wrote:
    While you're example works, mine doesn't, it has to do with the
    class
    assignment. If you actually bother to do anything with the class, it
    doesn't work.
    $ php -r 'class blah { function __destruct() { throw new Exception
    ("exception
    thrown"); } } $blah = new blah();'
    give that a try and see what happens
    (;
    also http://bugs.php.net/bug.php?id=33598 clearly states that
    they cannoy be
    thrown in the destructor.
    Errrr... *shrug*
    On Fri, 16 Dec 2005 20:38:20 +0100, Marcus Boerger wrote
    Hello Daine,

    marcus@zaphod /usr/src/PHP_5_1 $ php -r 'class A{function
    __destruct(){throw new Exception("A");}} new A;' make:
    `sapi/cli/php' is up to date.

    Fatal error: Uncaught exception 'Exception' with message 'A' in
    Command line code:1 Stack trace:
    #0 Command line code(1): A::__destruct()
    #1 {main}
    thrown in Command line code on line 1

    As the code above clearly show, exceptions can be thrown.

    marcus

    Friday, December 16, 2005, 3:17:54 PM, you wrote:
    Is there any reason why one is not allowed to throw an
    exception in the
    destructor of a class?
    I mean, it makes sense, considering this is not always the
    final step
    of code,
    and it is usually used for finalising things, and it would be a
    good
    idea to
    know if anything goes wrong at that stage.
    Otherwise is there any compromise one can use to "emulate" this
    feature?
    Daine Mamacos.
    --
    random signature
    Best regards,
    Marcus

    --
    PHP Internals - PHP Runtime Development Mailing List
    To unsubscribe, visit: http://www.php.net/unsub.php
    --
    random signature
    --
    Best regards,
    Marcus mailto:mail@marcus-boerger.de

    --
    random signature

    --
    PHP Internals - PHP Runtime Development Mailing List
    To unsubscribe, visit: http://www.php.net/unsub.php
    --
    PHP Internals - PHP Runtime Development Mailing List
    To unsubscribe, visit: http://www.php.net/unsub.php
    --
    random signature
    Best regards,
    Marcus
    --
    random signature

    --
    PHP Internals - PHP Runtime Development Mailing List
    To unsubscribe, visit: http://www.php.net/unsub.php

    --
    random signature
  • Marcus Boerger at Dec 21, 2005 at 12:31 am
    Hello Daine,


    as far as i can tell that assumption is correct. Destructor calls are not
    reliable in shutdown. That is they are at one point all called. For any
    destructor that creates a new object the destructor of that new object might
    not be called. Plus a bunch of other unexpected behavior.

    regards
    marcus

    Wednesday, December 21, 2005, 1:20:36 AM, you wrote:
    I see where all this is going.
    As long as the destructor is not called as part of the cleanup code, it
    works fine.
    Is that assumption correct?
    On Wed, 21 Dec 2005 00:14:15 +0000, Daine Mamacos wrote
    Marcus,
    I'm not trying to argue with you, I'm just after some help.
    You are confusing me somewhat.
    The php manual clearly states:
    "Note: Attempting to throw an exception from a destructor causes a
    fatal error." I'm somewhat convinced that you cannot throw an
    exception from a destructor, well you can, but it gets you nowhere.

    What does forcing the call of a destructor have to do with this conversation?

    If you can think of a way of working around this, that would be
    greatly appreciated.

    Anyway,
    Thanks
    Daine Mamacos

    On Tue, 20 Dec 2005 21:27:30 +0100, Marcus Boerger wrote
    Hello Daine,

    a) i didn't contradict myself - you obviously didn't really follow
    what i wrote

    b) you can force calling the destructor by using unset() or = null;
    but only if reference count is 1.
    c) exceptions are 'thrown' not called, maybe you didn't use throw new
    exception here or you were just writing a bit weired?
    d) as said already several times (not only to you) exceptions *can*
    be thrown in destructors

    e) this doesn't belong in internals@

    regards
    marcus

    Tuesday, December 20, 2005, 6:22:31 PM, you wrote:
    I agree completely...
    I think the GC should be better documented.
    I also would like someone to tell me why exceptions cannot be called in the
    destructor? Since they can't, this means the reliability of a destructor is
    uncontrolled and nothing can be done to see if this completes successfully.
    This in some way or another, renders them completely useless if you require
    them to complete an operation and at least have the peace of mind that you
    will be able to deal with errors rather than the application throwing a fatal
    error.
    On Tue, 20 Dec 2005 11:38:34 -0500, Alan Pinstein wrote
    Your last post also indicates, that because the destructors are
    only called
    after script termination, the scope of an object is global, always.
    Is this true?
    This isn't true, at least empirically. Destructors are called when
    the GC frees the object.

    For many objects, this is at script termination. But if you null out
    the ref to an object, it will occur immediately.

    $a = new A();
    $a = null; // destructor called just after this line

    I am not certain that this should be considered *predictable*
    behavior, as the behavior of the GC is not well/publicly documented
    to my knowledge, and thus this is a reasonable question for the
    internals list.

    Personally I would like to see more documentation of how GC works so
    that we as developers can depend on it a little better for OO
    cleanup activities. I have another thread going that still remains
    unanswered about how to prevent circular references to objects that
    deadlock the GC.

    Alan
    Also, I've called fwrite in a destructor before, so clearly not all
    IO is
    terminated before the destructor is called.
    When you refer to output facility, what are you talking about?

    Many thanks
    Daine Mamacos.


    On Mon, 19 Dec 2005 20:16:07 +0100, Marcus Boerger wrote
    Hello Daine,

    you still don't get it. Your problem is the way php works. You
    cannot put any output functionality in destructors because they are
    called *after* your scipt is being terminted (to be precise after
    the output facility has been shutdown on script termination).

    This is btw a question the general php list.

    marcus

    Monday, December 19, 2005, 11:07:53 AM, you wrote:
    While you're example works, mine doesn't, it has to do with the
    class
    assignment. If you actually bother to do anything with the class, it
    doesn't work.
    $ php -r 'class blah { function __destruct() { throw new Exception
    ("exception
    thrown"); } } $blah = new blah();'
    give that a try and see what happens
    (;
    also http://bugs.php.net/bug.php?id=33598 clearly states that
    they cannoy be
    thrown in the destructor.
    Errrr... *shrug*
    On Fri, 16 Dec 2005 20:38:20 +0100, Marcus Boerger wrote
    Hello Daine,

    marcus@zaphod /usr/src/PHP_5_1 $ php -r 'class A{function
    __destruct(){throw new Exception("A");}} new A;' make:
    `sapi/cli/php' is up to date.

    Fatal error: Uncaught exception 'Exception' with message 'A' in
    Command line code:1 Stack trace:
    #0 Command line code(1): A::__destruct()
    #1 {main}
    thrown in Command line code on line 1

    As the code above clearly show, exceptions can be thrown.

    marcus

    Friday, December 16, 2005, 3:17:54 PM, you wrote:
    Is there any reason why one is not allowed to throw an
    exception in the
    destructor of a class?
    I mean, it makes sense, considering this is not always the
    final step
    of code,
    and it is usually used for finalising things, and it would be a
    good
    idea to
    know if anything goes wrong at that stage.
    Otherwise is there any compromise one can use to "emulate" this
    feature?
  • Alan Pinstein at Dec 20, 2005 at 11:45 pm

    I also would like someone to tell me why exceptions cannot be
    called in the
    destructor? Since they can't, this means the reliability of a
    destructor is
    uncontrolled and nothing can be done to see if this completes
    successfully.
    Your question is kindof wrong... you can always throw exceptions in
    destructors. The problem is CATCHING them.

    I think probably in languages with GC's that throwing [uncaught]
    exceptions in destructors is probably a bad idea, unless you DESIRE
    termination as a result, as you don't know who's calling your
    destructor. I am not positive that this is a bad idea, but I think
    so... exceptions are meant to be caught. Uncaught exceptions are
    typically considered errors, and PHP considers them fatal.

    This is precisely what's happening to you. The destructor is called
    from the script termination cleanup code, outside of your program
    scope, and thus there's no try/catch to catch your exception. I
    suppose if you really want to do this just for logging, you could use:

    http://us2.php.net/manual/en/function.set-exception-handler.php

    But to me this seems like a bad idea.

    If you have some complicated tear-down machinery that you want to do
    try/catch with, try a method like "cleanup()" in your class and call
    it surrounded by try/catch to do your cleanup when you're done with
    the resource.

    Alan

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupphp-internals @
categoriesphp
postedDec 16, '05 at 2:18p
activeDec 21, '05 at 12:31a
posts12
users4
websitephp.net

People

Translate

site design / logo © 2022 Grokbase