Переменные и методы класса выдают ошибку компиляции

Вопросы программирования на Free Pascal, использования компилятора и утилит.

Модератор: Модераторы

Ответить
atom
незнакомец
Сообщения: 5
Зарегистрирован: 21.08.2016 10:33:59

Переменные и методы класса выдают ошибку компиляции

Сообщение atom »

Всем привет.
Столькнулся с такой проблемой в коде, которую не могу решить.
Описание системы:
Ubuntu 14.04, Lazarus 1.6, FPC 3.0, x86_64-linux-gtk2.

Есть вспомогательный класс T_Global, располагающийся в модуле U_Globals.pas. В нем описаны всякие вспомогательные методы, требующиеся один раз где-либо в специфическом коде или наоборот, в нескольких других классах. Так же использую его для хранения глобальных переменных.

Код: Выделить всё

unit U_Globals;

{$mode objfpc}{$H+}

type

  { T_Global }

  T_Global = class
  public
    class function getWorkDir: String;
    class function getIniFileName:String;
    class function getTransFileName(const aLng: String):String;

    class function getNameFromClassName(Obj:TObject):String;
    class function isFileReadOnly(const aFileName:String): Boolean;

    class function makeMenuItem(const aOwner:TComponent; const aAction: TAction): TMenuItem;
  end;
.......


И вот, при использовании внутри другого метода объекта возникает ошибка:

Код: Выделить всё

u_projectsform.pas(411,19) Error: identifier idents no member "makeMenuItem"


хотя код в этом модуле очень даже безобидный

Код: Выделить всё

...
  with T_Global do
  begin
    M := T_Global.makeMenuItem(Self, newProject);

    //makeMenuItem(Self, newProject);
    pm_lvProj.Items.Add(M);
    M := T_Global.makeMenuItem(Self, editProject);
    pm_lvProj.Items.Add(M);
    M := T_Global.makeMenuItem(Self, copyProject);
    pm_lvProj.Items.Add(M);
    M := T_Global.makeMenuItem(Self, deleteProject);
    pm_lvProj.Items.Add(M);
    pm_lvProj.Items.Add(T_Global.makeMenuItem(Self, nil));
    M := T_Global.makeMenuItem(Self, connectDB);
    pm_lvProj.Items.Add(M);
    M := T_Global.makeMenuItem(Self, disconnectDB);
    pm_lvProj.Items.Add(M);
    lv_Prj.PopupMenu := pm_lvProj;
  end;
....

При этом модуль описан в секции uses, методы и переменные стопроцентов существуют и даже Лазарус их находит по щелчку мыши.
Может кто-нибудь подсказать, что я делаю не так? Вероятно нужны какие либо специфические дефайны для использования таких методов и переменных?
SSerge
энтузиаст
Сообщения: 971
Зарегистрирован: 12.01.2012 05:34:14
Откуда: Барнаул

Сообщение SSerge »

with уберите
atom
незнакомец
Сообщения: 5
Зарегистрирован: 21.08.2016 10:33:59

Сообщение atom »

SSerge писал(а):with уберите


В первоначальной версии этого не было. И убирал, и добавлял. Сути дела это не меняет. Ошибка остается прежней.
Обнаружил, что если создать глобальную переменную GLOBAL, в инициализации модуля U_Globals создавать объект с этой переменной, то компилятор не находит уже эту глобальную переменную (GLOBAL). Вообще мистика.
Тоже самое происходит, если методы и переменные сделать объектными - переменную то не находит.
Mirage
энтузиаст
Сообщения: 881
Зарегистрирован: 06.05.2005 20:29:07
Откуда: Russia
Контактная информация:

Сообщение Mirage »

T_Global это только название класса, или еще и переменная так названа? Полный код бы.
resident
энтузиаст
Сообщения: 605
Зарегистрирован: 13.03.2013 16:58:51

Сообщение resident »

atom
Не знаю, что посоветовать по вашим огрызкам кода. Может:

Код: Выделить всё

M := TMenuItem(T_Global.makeMenuItem(Self, newProject));


atom писал(а):Вероятно нужны какие либо специфические дефайны для использования таких методов и переменных?

Каких ещё переменных? Вы ж даже не показали, как объявлены переменные. М, это что?
atom
незнакомец
Сообщения: 5
Зарегистрирован: 21.08.2016 10:33:59

Сообщение atom »

resident писал(а):atom
Каких ещё переменных? Вы ж даже не показали, как объявлены переменные. М, это что?


M - это локальная переменная метода, типа TMenuItem. Кастинг попробую, но опять же - это костыль.
Аватара пользователя
Лекс Айрин
долгожитель
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград
Контактная информация:

Сообщение Лекс Айрин »

atom писал(а):При этом модуль описан в секции uses, методы и переменные стопроцентов существуют и даже Лазарус их находит по щелчку мыши.

Имя класса выдает код типа:

Код: Выделить всё

FMain.MenuAbout.ToString

Ну и стоит учитывать, что для совершенно левого указателя не существует данной функции, так что стоит включить данный код в обработчик ошибок.

Возможно, стоит перенести подключение из секции interface в секцию implementation
atom
незнакомец
Сообщения: 5
Зарегистрирован: 21.08.2016 10:33:59

Сообщение atom »

Лекс Айрин писал(а):
atom писал(а):При этом модуль описан в секции uses, методы и переменные стопроцентов существуют и даже Лазарус их находит по щелчку мыши.

Имя класса выдает код типа:

Код: Выделить всё

FMain.MenuAbout.ToString

Ну и стоит учитывать, что для совершенно левого указателя не существует данной функции, так что стоит включить данный код в обработчик ошибок.


Прошу прощение, но это откуда?

Возможно, стоит перенести подключение из секции interface в секцию implementation


Тоже попробую, но боюсь ошибки циклической ссылки потом получить. Но попробовать стоит.
Аватара пользователя
Лекс Айрин
долгожитель
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград
Контактная информация:

Сообщение Лекс Айрин »

atom писал(а):но боюсь ошибки циклической ссылки потом получить.


обычно так делают для исключения циклической ссылки.

atom писал(а):Прошу прощение, но это откуда?


Это из среды Lazarus. ToString объявлена в TObject и, собственно, явно для использования самой средой и компонентами. Иногда стоит пролистать список методов, которые система выдает для каждого объекта... там будут ну очень интересные вещи.
atom
незнакомец
Сообщения: 5
Зарегистрирован: 21.08.2016 10:33:59

Сообщение atom »

Лекс Айрин писал(а):обычно так делают для исключения циклической ссылки.


Циклические ссылки как раз и получаются, если оба юнита имеют в интерфейсной части описания друг на друга. В моем коде как раз стоит в implementation.

Это из среды Lazarus. ToString объявлена в TObject и, собственно, явно для использования самой средой и компонентами. Иногда стоит пролистать список методов, которые система выдает для каждого объекта... там будут ну очень интересные вещи.


То есть это аналог функции ClassName. Просто стараюсь оставить совместимость с Дельфей.
Хотя определение класса - это дело в run-time. До этого момента не доходит - ошибка описанная выше на этапе компиляции.
zub
долгожитель
Сообщения: 2889
Зарегистрирован: 14.11.2005 22:51:26
Контактная информация:

Сообщение zub »

Вообще мистика.

Сделай минимальный пример с ошибкой и мистика рассеется
Аватара пользователя
Лекс Айрин
долгожитель
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград
Контактная информация:

Сообщение Лекс Айрин »

atom писал(а):То есть это аналог функции ClassName. Просто стараюсь оставить совместимость с Дельфей.


Да, это полный аналог, так что можно оставить и ClassName.
SSerge
энтузиаст
Сообщения: 971
Зарегистрирован: 12.01.2012 05:34:14
Откуда: Барнаул

Сообщение SSerge »

Лекс Айрин писал(а):Да, это полный аналог


Ужель? Какбы это скорее всего сделано дельфой для того, чтобы порождать из TObject сущности, компилируемые для исполняющей среды .net framework
И там это совсем не "имя класса"
Аватара пользователя
Лекс Айрин
долгожитель
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград
Контактная информация:

Сообщение Лекс Айрин »

SSerge "Если оно выглядит как утка, плавает как утка и крякает как утка, то это утка".

И вообще-то у меня нет Дельфи, так что говорить могу только за Lazarus.
Ответить