![]() |
|
|
|||||||
| Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
|
Опции темы | Поиск в этой теме | Опции просмотра |
|
#1
|
||||
|
||||
|
Сей вопрос не особо важен и вызван чрезмерной ленью.
Суть: Есть некоторая функция проверки условия. Вызывается из целого ряда других функций и процедур. Выдает сообщение об ошибке (если условие не выполнилось). Вопрос: Можно ли из этой функции проверки прервать выполнение той функции, из которой она была вызвана? Мотивация: На данный момент есть несколько функций проверки. Их результат критичен (то есть если результат отрицательный, дальше ничего выполняться не должно). В большинстве случаев они используются все, но местами требуется использовать их поодиночке. Выглядит это так: Код:
function ФункцияПроверки1:boolean; begin ****** end; Function ФункцияПроверки2:boolean; begin ****** end; Function ФункцияПроверки3:boolean; begin ****** end; procedure ВыполняемаяПроцедура1; begin if ФункцияПроверки1 then begin *** if ФункцияПроверки2 then begin *** if ФункцияПроверки3 then begin ***** ***** ***** end; end; end; end; procedure ВыполняемаяПроцедура2; begin if ФункцияПроверки1 then begin *** if ФункцияПроверки2 then begin *** if ФункцияПроверки3 then begin ***** ***** ***** end; end; end; end; Код:
procedure ПроцедураПроверки1; begin if Условие=false then begin ****** завершить подпрограмму, из которой была вызвана проверка; end; end; procedure ПроцедураПроверки2; begin if Условие=false then begin ****** завершить подпрограмму, из которой была вызвана проверка; end; end; procedure ПроцедураПроверки3; begin if Условие=false then begin ****** завершить подпрограмму, из которой была вызвана проверка; end; end; procedure ВыполняемаяПроцедура1; begin ПроцедураПроверки1; //дальше не должно пойти, если условие не выполнено *** ПроцедураПроверки2; //дальше не должно пойти, если условие не выполнено *** ПроцедураПроверки3; //дальше не должно пойти, если условие не выполнено *** *** *** end; procedure ВыполняемаяПроцедура2; begin ПроцедураПроверки1; //дальше не должно пойти, если условие не выполнено *** ПроцедураПроверки2; //дальше не должно пойти, если условие не выполнено *** ПроцедураПроверки3; //дальше не должно пойти, если условие не выполнено *** *** *** end; |
|
#2
|
||||
|
||||
|
Цитата:
|
|
#3
|
||||
|
||||
|
Abort()
или raise EAbort.Create |
|
#4
|
|||
|
|||
|
Код:
if not ФункцияПроверки1 then exit; *** if not ФункцияПроверки1 then exit; |
|
#5
|
||||
|
||||
|
Цитата:
|
|
#6
|
||||
|
||||
|
Цитата:
|
|
#7
|
||||
|
||||
|
Код:
procedure ВыполняемаяПроцедура1; begin if not ФункцияПроверки1 then Exit; *** if not ФункцияПроверки2 then Exit; *** if not ФункцияПроверки3 then Exit; ***** ***** ***** end; |
|
#8
|
||||
|
||||
|
Цитата:
Есть еще способы? Может, есть команда, которая разом прерывает выполнения всех функций (в том числе и рекурсивных) и переходит в режим ожидания действий пользователя? Ну, типа Application.Terminate, только без полного завершения программы, а лишь завершение активности. ![]() А потоки в этом помогут, как думаете? Последний раз редактировалось morebeauty, 16.11.2012 в 11:43. |
|
#9
|
|||
|
|||
|
Цитата:
|
|
#10
|
||||
|
||||
|
Если ф-ии с одинаковыми параметрами, можно ссылки на них свалить в массив и в одном цикле прогнать.
|
|
#11
|
||||
|
||||
|
Код:
procedure ВыполняемаяПроцедура1; begin if not ФункцияПроверки1 then Exit; *** if not ФункцияПроверки2 then Exit; *** if not ФункцияПроверки3 then Exit; ***** ***** ***** end; Вот поэтому я и хочу свести все действия на невыполнение условия к процедуре проверки. Тогда код будет более гибким ИМХО. Цитата:
Цитата:
|
|
#12
|
||||
|
||||
|
Вот рабочий метод из софтины которую я сейчас пишу. Используется куча Exit'ов, вполне нормальный код, ИМХО. Ничего криминального я тут не вижу.
Код:
function TTestThread.CheckLoops: Boolean;
{$DEFINE new_alg}
{.$DEFINE old_alg}
const
LoopWait = 5000;
LoopsState:array [1..3,1..2] of Boolean =
(
(True,False),(False,True),(True,True)
);
var
Points:Integer;
i: Integer;
begin
AddToLog('Вход в процедуру CheckLoops');
Result:=False;
if not (Loop1(False) and Loop2(False)) then
begin
AddToLog('Ошибка управления шлейфами.');
AddToLog(Format('Выход из процедуры CheckLoops, с результатом %s',[BoolToStr(Result,True)]));
Exit;
end;
Sleep(LoopWait);
//Залить настройку
if not WriteSettingForLoops then
begin
AddToLog('Ошибка настройки шлейфов');
AddToLog(Format('Выход из процедуры CheckLoops, с результатом %s',[BoolToStr(Result,True)]));
Exit;
end;
Points:=GetPoint;
if Points<0 then
begin
AddToLog('Ошибка пролучения значения +point');
AddToLog(Format('Выход из процедуры CheckLoops, с результатом %s',[BoolToStr(Result,True)]));
Exit;
end;
//Сформировать события
for i := Low(LoopsState) to High(LoopsState) do
begin
if not (Loop1(LoopsState[i,1]) and Loop2(LoopsState[i,2])) then
begin
AddToLog('Ошибка управления шлейфами.');
AddToLog(Format('Выход из процедуры CheckLoops, с результатом %s',[BoolToStr(Result,True)]));
Exit;
end;
Inc(Points);
if i=3 then
Inc(Points);
Sleep(LoopWait);
{$IFDEF new_alg}
if not (Loop1(False) and Loop2(False)) then
begin
AddToLog('Ошибка управления шлейфами.');
AddToLog(Format('Выход из процедуры CheckLoops, с результатом %s',[BoolToStr(Result,True)]));
Exit;
end;
{$ENDIF}
if not CheckPointsCount(Points) then
begin
AddToLog('Текущее состояние истории не соответствует ожидаемому');
FTestResult.LoopsTests[i]:=False;
end
else
begin
FTestResult.LoopsTests[i]:=True;
AddToLog(Format('Для состояния шлейфов [%s,%s] тест прошел успешно',[BoolToStr(LoopsState[i,1]),BoolToStr(LoopsState[i,2])]));
end;
{$IFDEF old_alg}
if not (Loop1(False) and Loop2(False)) then
begin
AddToLog('Ошибка управления шлейфами.');
AddToLog(Format('Выход из процедуры CheckLoops, с результатом %s',[BoolToStr(Result,True)]));
Exit;
end;
{$ENDIF}
Sleep(LoopWait);
end;
//Очистить настройки шлейфов
if not ClearSettingsForLoops then
begin
AddToLog('Ошибка очистки настроек шлейфов');
AddToLog(Format('Выход из процедуры CheckLoops, с результатом %s',[BoolToStr(Result,True)]));
Exit;
end;
Result:=True;
AddToLog(Format('Выход из процедуры CheckLoops, с результатом %s',[BoolToStr(Result,True)]));
end; |
|
#13
|
||||
|
||||
|
Код:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
procedure ExceptionEvent(Sender: TObject; E: Exception);
procedure DoCheck;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
Application.OnException:=ExceptionEvent;
end;
procedure TForm1.ExceptionEvent(Sender: TObject; E: Exception);
begin
// ShowMessage(E.Message);
end;
procedure TForm1.DoCheck;
begin
if True then raise Exception.Create('Oops');
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
DoCheck;
end;
end.но с Exit красивее |
|
#14
|
||||
|
||||
|
Код:
procedure TForm1.ExceptionEvent(Sender: TObject; E: Exception); begin // ShowMessage(E.Message); end; Вы извините меня, я не очень шарю. Мануалы не всегда помогают. В этом, например, случае. Поэтому и спрашиваю. |
|
#15
|
||||
|
||||
|
Цитата:
![]() В примере ниже "Beep" никогда не вызовется, так как первый же "Abort" прервёт одним махом все вложенные (рекурсивные) вызовы и перейдёт "в режим ожидания действий пользователя" (если конечно не встретится другого обработчика except): Код:
procedure TForm1.Button4Click(Sender: TObject);
procedure Recursion(Level: Integer);
begin
if Level = 100 then Abort;
Recursion(Level + 1);
Beep;
end;
begin
Recursion(0);
end; |
| Этот пользователь сказал Спасибо poli-smen за это полезное сообщение: | ||
morebeauty (19.11.2012)
| ||