конструкция finally - неужели бестолковая?

zerkms

TDD infected
Команда форума
тебе шашечки или ехать?
Во поедете со своим кодом только тогда, когда будет 100% гарантия, что rollback(); не вывалит исключения. И тогда - привет-привет, unlink_tmp_file();, никогда не вызовется.

Предвосхищая вопросы - роллбэк обвалится тогда, когда мы потеряли соединение с базой, к примеру.
 

zerkms

TDD infected
Команда форума
to all: какой ещё сахар, это самостоятельная конструкция, которую "эмулировать" с учётом всех деталей вы замучаетесь (как уже показал fixxxer своим кодом - ошибиться более чем просто).
 

AmdY

Пью пиво
Команда форума
zerkms
эмулировать можно вложенным try catch, но автор как бы сам это знает и пишет, что это вызовет дублирование кода.

конструкция, однозначно, была бы не лишняя.
 

zerkms

TDD infected
Команда форума
AmdY
Вложенный try-catch + дополнительный код ПОСЛЕ, для повторного проброса эксепшна, с последующей потерей места изначального выброса эксепшна (?)
 

AmdY

Пью пиво
Команда форума
ха, посмотрел как в java, они так же делают вложенный try catch в finally
а если его не ловить, то срабатывает один из трёх вариантов, какой?
1. код выполняется больше
2. выше поднимается первый эксепшин
3. выше поднимается вложенный эксепшин
здесь нужны люди, знающие вражеские языки.

гы, фиг всё же реализуешь, блок выполняется даже в случае return http://www.java-tips.org/java-se-tips/java.lang/use-of-finally-clause.html

p.s. Это излишне сложно для php, проще этого не хотеть, чтобы не приходилось эмулировать.
 

Вурдалак

Продвинутый новичок
AmdY, в C# сейчас проверил.
Код:
int x = 0;

try
{
    try
    {
        x /= x; // DivideByZeroException
    }
    finally
    {
        throw new OverflowException();
    }
}
catch(Exception e)
{
    System.Console.WriteLine(e.Message);
}
Arithmetic operation resulted in an overflow.
Т.е. 3-й вариант. Там ещё есть свойство e.InnerException (аналог previous Exception в PHP), но оно пустое. Хотя кажется более логичным, чтобы в нём был объект класса DivideByZeroException.
 

zerkms

TDD infected
Команда форума
Вурдалак
Иннер нужно в явном виде передавать самому (другое дело что у тебя его в finally нету :) )
 

zerkms

TDD infected
Команда форума
Вурдалак
Вот именно. Чтобы появился иннер - нужно его в ЯВНОМ ВИДЕ передать в новый эксепшн, а в finally его взять неоткуда.
 

Вурдалак

Продвинутый новичок
zerkms, т.е. если в finally у тебя выбрасывается исключение, то узнать о предыдущем исключении ты ничего не сможешь?
 

tz-lom

Продвинутый новичок
симулятор finaly аля пример выше (с некоторыми НО по поводу размещения в тексте, решается оборачиванием в анонимку)
PHP:
<?php
class Finaly
{
    protected $callback;
    
    public function __construct($callback)
    {
        $this->callback = $callback;
    }
    
    public function __destruct()
    {
        call_user_func($this->callback);
    }
}

function test()
{
        $a = new Finaly(function(){ throw new Exception('overflow'); });
        throw new Exception('divide by zero');
}

try
{
    test();
}
catch(Exception $e)
{
    echo $e->getMessage(),"\n";
}
echo "well done\n";
 

Mols

Новичок
хз... ващет ну ни разу мне такого не хотелось.
может оно кому-то и надо...но если вспомнить те примеры, которые ТС нам предоставил, дык вполне достаточно в деструкторе самого класса выполнить вызов требуемого кода.
 
Сверху