Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Захват переменной в анонимной процедуре / 25 сообщений из 30, страница 1 из 2
06.06.2019, 08:46
    #39823216
wsnet
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Захват переменной в анонимной процедуре
Коллеги, как вернуть значение переменной.

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
procedure CallActionFrm(var id: Integer);
var
  AfrmBaseDictionaryList: TfrmBaseDictionaryList;
begin
  with TfrmBaseDictionaryList.Create(UniApplication) do
  begin
    ShowModal(
      procedure(Sender: TComponent; AResult: Integer)
      begin
        if AResult = mrOk then
        begin
          id := 100;
        end;
      end
      );
  end;
end;



Ошибка - E2555 Cannot capture symbol 'id'

Как обойти?
...
Рейтинг: 0 / 0
06.06.2019, 09:35
    #39823245
X-Cite
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Захват переменной в анонимной процедуре
Присвоить ее локальной. Захватить локальную. Потом по выходу локальную опять присвоить в var параметр.
var и иногда const не захватываются.
...
Рейтинг: 0 / 0
06.06.2019, 09:43
    #39823251
wsnet
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Захват переменной в анонимной процедуре
X-Cite, делаю, не получается:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
procedure CallActionFrm2(var I: integer);
var
  AfrmBaseDictionaryList: TfrmBaseDictionaryList;
  tmp: Integer;
begin
  tmp := I;
  with TfrmBaseDictionaryList.Create(UniApplication) do
  begin
    ShowModal(
      procedure(Sender: TComponent; AResult: Integer)
      begin
        if AResult = mrOk then
        begin
          tmp := 100;
        end;
      end
      );
    I := tmp;
  end;
end;

...

procedure TfrmAdmPlanItem.btnSearchClick(Sender: TObject);
var
  id: Integer;
begin
  id := 1;
  CallActionFrm2(id);
  edtInn.Text := IntToStr(id); // получаю id = 1, а не 100!
end;
...
Рейтинг: 0 / 0
06.06.2019, 10:09
    #39823269
X-Cite
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Захват переменной в анонимной процедуре
А вы сделайте
Код: pascal
1.
2.
3.
4.
if AResult = mrOk then
  tmp := 100
else
  tmp := 200;


Вангую что вернется 200
...
Рейтинг: 0 / 0
06.06.2019, 10:54
    #39823303
wsnet
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Захват переменной в анонимной процедуре
X-CiteА вы сделайте
Код: pascal
1.
2.
3.
4.
if AResult = mrOk then
  tmp := 100
else
  tmp := 200;


Вангую что вернется 200

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
procedure CallActionFrm2(var I: integer);
var
  AfrmBaseDictionaryList: TfrmBaseDictionaryList;
  tmp: Integer;
begin
  tmp := I;
  with TfrmBaseDictionaryList.Create(UniApplication) do
  begin
    ShowModal(
      procedure(Sender: TComponent; AResult: Integer)
      begin
        if AResult = mrOk then
        begin
          tmp := 100;
        end
        else
          tmp := 200;
      end
      );
    I := tmp;
  end;
end;

...

procedure TfrmAdmPlanItem.btnSearchClick(Sender: TObject);
var
  id: Integer;
begin
  id := 1;
  CallActionFrm2(id);
  edtInn.Text := IntToStr(id); // Возвращает 1!
end;
...
Рейтинг: 0 / 0
06.06.2019, 11:08
    #39823307
Kazantsev Alexey
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Захват переменной в анонимной процедуре
wsnet,

А так не сработает?
Код: pascal
1.
PInteger(@id)^ := 100;
...
Рейтинг: 0 / 0
06.06.2019, 12:30
    #39823372
wsnet
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Захват переменной в анонимной процедуре
Kazantsev Alexeywsnet,

А так не сработает?
Код: pascal
1.
PInteger(@id)^ := 100;



Тоже самое

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
procedure CallActionFrm2(var I: integer);
var
  AfrmBaseDictionaryList: TfrmBaseDictionaryList;
  tmp: Integer;
  PInteger: ^Integer;
begin
  PInteger := @I;
  with TfrmBaseDictionaryList.Create(UniApplication) do
  begin
    ShowModal(
      procedure(Sender: TComponent; AResult: Integer)
      begin
        if AResult = mrOk then
        begin
          PInteger^ := 100; //id = 1!
          ShowMessage('test');
        end
        else
          PInteger^ := 200;
      end
      );
  end;
end;
...
Рейтинг: 0 / 0
06.06.2019, 12:49
    #39823388
alekcvp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Захват переменной в анонимной процедуре
wsnet,

А отладчик на строке "I := tmp;" какое значение tmp показывает?
...
Рейтинг: 0 / 0
06.06.2019, 12:52
    #39823393
alekcvp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Захват переменной в анонимной процедуре
В 10.2 вот этот код работает корректно:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
type
  TPR = reference to procedure;

procedure Test2(PR: TPR);
begin
  PR();
end;

procedure Test(var Id: Integer);
var
  Idd: Integer;
begin
  Idd := Id;
  Test2(procedure
    begin
      Idd := 200;
    end);
  Id := Idd;
end;

var
  Id: Integer;
begin
  try
    Id := 1;
    WriteLn(Id);
    Test(Id);
    WriteLn(Id);
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  ReadLn;
end.


А у вас?
...
Рейтинг: 0 / 0
06.06.2019, 14:16
    #39823464
X-Cite
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Захват переменной в анонимной процедуре
А анонимная функция вызывается? Вангую, что нет.
...
Рейтинг: 0 / 0
06.06.2019, 14:21
    #39823475
wsnet
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Захват переменной в анонимной процедуре
X-CiteА анонимная функция вызывается? Вангую, что нет.

Да она отрабатывает как нужно.
...
Рейтинг: 0 / 0
06.06.2019, 14:51
    #39823506
X-Cite
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Захват переменной в анонимной процедуре
Вызов ShowModal синхронный или асинхронный?
...
Рейтинг: 0 / 0
06.06.2019, 15:21
    #39823535
wsnet
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Захват переменной в анонимной процедуре
X-Cite, пробую и синхронно и асинхронно все тоже.

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
procedure CallActionFrm2(var I: integer);
var
  AfrmBaseDictionaryList: TfrmBaseDictionaryList;
  tmp: Integer;
  PInteger: ^Integer;
begin
  PInteger := @I;
  UniSession.Synchronize;
  with TfrmBaseDictionaryList.Create(UniApplication) do
  begin
    ShowModal(
      procedure(Sender: TComponent; AResult: Integer)
      begin
        if AResult = mrOk then
        begin
          PInteger^ := 100;
          ShowMessage('test'); //Отрабатывает! Но переменная - не  захватывается. 
        end
        else
          PInteger^ := 200;
      end
      );
  end;
end;
...
Рейтинг: 0 / 0
06.06.2019, 15:27
    #39823542
wsnet
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Захват переменной в анонимной процедуре
Если я пробую вызвать через метод объекта, указав тип процедуры - как метод объекта, все работает, но так бы не хотелось - ибо хочу обработку переменной Id иметь в одной процедуре в зависимости от mrOk или mrCancel:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
type
TCallBack = procedure(Sender: TComponent; Res: Integer) of object;

procedure CallActionFrm(var Id: Integer; pCallBack: TCallBack = nil);
var
  vMsg: TfrmBaseDictionaryList;
begin
  vMsg := TfrmBaseDictionaryList.Create(UniApplication);
  if Assigned(pCallBack) then
  begin
    vMsg.ShowModal(pCallBack);
    Id := 200;// ура переменная захватывается!
  end;
end;

procedure TfrmAdmPlanItem.btnSearchClick(Sender: TObject);
var id:Integer;
begin
id = 100;
CallActionFrm( id, DoCallBack);
end;
...
Рейтинг: 0 / 0
06.06.2019, 15:47
    #39823554
wsnet
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Захват переменной в анонимной процедуре
alekcvpВ 10.2 вот этот код работает корректно:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
type
  TPR = reference to procedure;

procedure Test2(PR: TPR);
begin
  PR();
end;

procedure Test(var Id: Integer);
var
  Idd: Integer;
begin
  Idd := Id;
  Test2(procedure
    begin
      Idd := 200;
    end);
  Id := Idd;
end;

var
  Id: Integer;
begin
  try
    Id := 1;
    WriteLn(Id);
    Test(Id);
    WriteLn(Id);
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  ReadLn;
end.


А у вас?

Этот код работает! Но в чем принципиальное отличие от моего метода - там переменная не захватывается!
...
Рейтинг: 0 / 0
06.06.2019, 16:53
    #39823599
ziv-2014
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Захват переменной в анонимной процедуре
wsnet, Анонимная функция - это интерфейс. В интерфейсе есть переменная, которая отвечает за это. Погляди в отладчике, присваивается ли ей значение.
...
Рейтинг: 0 / 0
06.06.2019, 16:56
    #39823604
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Захват переменной в анонимной процедуре
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
procedure CallActionFrm2(var I: integer);
var
  AfrmBaseDictionaryList: TfrmBaseDictionaryList;
  tmp: Integer;
  PInteger: ^Integer;
begin
  PInteger := @I;
  UniSession.Synchronize;
  with TfrmBaseDictionaryList.Create(UniApplication) do
  begin
    ShowModal(
      procedure(Sender: TComponent; AResult: Integer)
      begin
        if AResult = mrOk then
        begin
          PInteger^ := 100;
          ShowMessage('test');
        end
        else
          PInteger^ := 200;
      end
      );
  end;
  ShowMessage('Exit');
end;

В каком порядке появятся сообщения?
...
Рейтинг: 0 / 0
06.06.2019, 19:35
    #39823699
wsnet
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Захват переменной в анонимной процедуре
_Vasilisk_
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
procedure CallActionFrm2(var I: integer);
var
  AfrmBaseDictionaryList: TfrmBaseDictionaryList;
  tmp: Integer;
  PInteger: ^Integer;
begin
  PInteger := @I;
  UniSession.Synchronize;
  with TfrmBaseDictionaryList.Create(UniApplication) do
  begin
    ShowModal(
      procedure(Sender: TComponent; AResult: Integer)
      begin
        if AResult = mrOk then
        begin
          PInteger^ := 100;
          ShowMessage('test');
        end
        else
          PInteger^ := 200;
      end
      );
  end;
  ShowMessage('Exit');
end;

В каком порядке появятся сообщения?

Странно, но сначала 'Exit', а только потом 'test'. Отчего так?
...
Рейтинг: 0 / 0
06.06.2019, 19:36
    #39823700
X-Cite
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Захват переменной в анонимной процедуре
UniApplication

У вас случаем не UniGui приложение?
...
Рейтинг: 0 / 0
06.06.2019, 19:38
    #39823701
X-Cite
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Захват переменной в анонимной процедуре
...
Рейтинг: 0 / 0
06.06.2019, 19:38
    #39823702
wsnet
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Захват переменной в анонимной процедуре
X-Cite, да UniGui.
...
Рейтинг: 0 / 0
06.06.2019, 19:40
    #39823703
X-Cite
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Захват переменной в анонимной процедуре
ShowModal doesn't block execution in UniGUI, use callbacks to execute your code after the form is closed
...
Рейтинг: 0 / 0
06.06.2019, 19:43
    #39823706
X-Cite
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Захват переменной в анонимной процедуре
Вызов то асинхронный. Конечно работать не будет... Локальные замыкания работают только при синхронном вызове анонимки.
Ваша строка кода
I := tmp;
Выполнится раньше чем вызовется анонимка.
...
Рейтинг: 0 / 0
06.06.2019, 19:58
    #39823711
wsnet
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Захват переменной в анонимной процедуре
X-CiteВызов то асинхронный. Конечно работать не будет... Локальные замыкания работают только при синхронном вызове анонимки.
Ваша строка кода
I := tmp;
Выполнится раньше чем вызовется анонимка.

Теперь ясно! Только в Callback буду получать значение теперь! Спасибо!
...
Рейтинг: 0 / 0
06.06.2019, 20:02
    #39823712
X-Cite
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Захват переменной в анонимной процедуре
X-Cite Локальные замыкания работают только при синхронном вызове анонимки
Я тут соврал..будут работать и при асинхронном..
Ведь внутри анонимки контекст уже захвачен...
А вот код после ShowModal у unigui выполнится раньше чем анонимка, это надо понимать...
...
Рейтинг: 0 / 0
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Захват переменной в анонимной процедуре / 25 сообщений из 30, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]