Ошибки PascalABC.NET

Ещё у вас IntelliSence не видит конструктор для auto class

Не компилирует

uses System.Reflection;
begin
var a:=MemberTypes.Event;
end.

хотя если добавить & то работает

Последнее исправили. В ближайшем обновлении выйдет

Как заставить процедуру Read работать именно как Read, а не Readln ? Исходная ситуация: пытаюсь в цикле ввести массив записей(5штук). Все элементы одной записи пытаюсь ввести в одну строку при помощи отдельных процедур Read. Делается это для того, чтобы каждый из вводимых элементов записи сразу-же контролировать по определенных критериям. Так вот, собственно проблема - процедура Read(каждая) постоянно срабатывает как Readln - то есть получает вводимое значение и переводит строку ввода на следующую строку экрана. Как мне добиться того, чтобы данная процедура работала в одной строке, как это и должно быть(и как это работает в том же древнем Турбо Паскале)? Если это никак нельзя исправить, то как мне реализовать самому данный функционал(как перегружать подпрограммы - я прочитал примеры).

Параметры системы: Windows 8.10. IDE PascalABC.NET версия 3.10 build 1200. Вот исходный код:

Const Maxx=5;

type MyType = record
 Fio : string;
 Summa : real;
 Kol : integer;
end;

var ArrMyType : array of MyType;
 i, j : integer;
Begin
 SetLength(ArrMyType, Maxx);
 for i:= 0 to Maxx-1 do begin
  write(' Введите ФИО: '); read(ArrMyType[i].Fio);
  write(' Введите cумму: '); read(ArrMyType[i].Summa);
  write(' Введите количество: '); read(ArrMyType[i].Kol);
  writeln;
  // Здесь  еще будет блок обработки каждого 
  // из вводимых значений полей каждой записи по определенным критериям
 end;
 
 writeln;
 
 for i:= 0 to Maxx-1 do begin
  write(' ФИО: ', ArrMyType[i].Fio);
  write(' Cумма: ', ArrMyType[i].Summa:7:2);
  write(' Количество: ', ArrMyType[i].Kol);
  writeln;
 end;
End.

Также возникает дополнительный баг - со второго элемента теряется ввод переменной ArrMyType[i].Fio - write выдаётся, а процедура ввода на этом элементе совсем не срабатывает…

Кстати, аналогичный код по вводу числового одномерного массива - процедура Read опять таки постоянно перескакивает после ввода значения на следующую строку!

Вот код:

Const Maxx=5;

var ArrM : array of Integer;
 i, j : integer;
Begin
 SetLength(ArrM, Maxx);
 for i:= 0 to Maxx-1 do begin
  write(' Введите ', i,'-й элемент: '); read(ArrM[i]);
  // Здесь  еще будет блок обработки каждого 
  // из вводимых значений массива по определенным критериям
  end;
  writeln; 
  writeln;

 for i:= 0 to Maxx-1 do  write(i,'. ', ArrM[i],'  ');
 
 writeln;
End.

В текущей версии перестал компилироваться такой код (раньше было нормально).

unit My;

interface
  
type A<T> = class
  data: T;
end;

function mka<T>(): A<T>;

implementation

function mka<T>() := new A<T>;
//           ^ ошибка, предописание и описание имеют разные типы возвр. значения

end.

Если указывать тип явно, то работает, но не хотелось бы увеличивать код.

А вы когда данные вводите, как ввод завершаете? в смысле каждого отдельного поля. не клавишей ли enter? если ей, то в таком случае вы сами строку переводите, и программа тут ни при чем. и как этот перевод строки повлияет на последующую валидацию, если данные введены и уже записаны в переменной?

любой оператор(процедура) ввода заканчивается тем, что Вы заносите вводимое значение в конкретную переменную, нажав клавишу “ввод”. Но процедуры Read и Readln тем и отличаются, что перевод строки должна вызвать только процедура ReadLn. Вы не понимаете различий между этими двумя процедурами(по аналогии с Write и WriteLn)? Нажав клавишу “ввод”, я всего лишь даю системе знать, что завершил ввод конкретного значения, а не даю команду системе изменить текущую строку на следующую. Понимаете?

Если нет - опишите, как вы реализуете программно(ту задачу, код которой я привел выше) ввод переменных одной записи в одну строку, с переходом к следующей строке только при переходе к следующей записи. Только не надо использовать одну процедуру ReadLn для ввода всех переменных одной записи. Ок?

или напишите код ввода массива из 50 элементов в одну строку.

Кстати, я уже сам реализовал данный функционал для разных типов переменных. Только вот при попытке вызвать “перезагруженную” процедуру Read выскакивает ошибка при выполнении кода: ‘Process is terminated due to StackOverflowException’, хотя при компиляции кода никаких ошибок не выдаёт. Или процедуру Read нельзя “перезагрузить” со своим обработчиком ввода?

Ну я пока так и не понял почему их принципиально вводить одной строкой, какой юзкейс и чем плоха разбивка. А я такие задачи даже в паскале пару лет решаю в формах, ввод в консоли сто лет уже не реализовывал. Там на поле ввода и валидацию можно набросить, и форматировать прям в ней же. А в вебе еще и placeholder’ы есть.

ты не понял, я ввожу их не одной строкой, а хочу, чтобы при вводе данных через Read строка(строка экрана, а не данных) оставалась той-же что и до ввода переменной, а не перескакивала на следующую строку экрана

Вопрос к Админу - почему я не могу “перезагрузить” подпрограмму Read на такую-же со своей реализацией? Ошибка описана на пару постов выше. Спасибо.

Этого сделать невозможно если первой Вы считываете строку. Строка считывается вся - до нажатия Enter, а не до пробела.

Чтобы сделать то, что Вы хотите, надо поступать так: вводить строку, разбивать её на лексемы и затем преобразовывать нужные лексемы к целым и вещественным:

var s := ReadlnString;
var ss := s.ToWords;
ArrMyType[i].Fio := ss[0];
ArrMyType[i].Summa := ss[1].ToReal;
ArrMyType[i].Kol := ss[2].ToInteger;

Этот способ решения - наиболее чистый.

Процедуру Read заставить нельзя - даже не пытайтесь.

могу ли я “перезагрузить” подпрограмму Read, написав эту процедуру со своей реализацией?

Боюсь, что это - расплата за полностью переработанный алгоритм вывода типов в коротких функциях. Напомню, что теперь в их телах допускаются лямбда-выражения - было за что бороться. Вернуть назад, конечно, можно, но не хочется.

Можно ли совместить хорошее в новой и старой версии? Мне кажется, что нет, но глубоко я это не исследовал. Запишите это пока в Issue на Github - пусть повисит.

Давайте использовать правильные термины - “переопределить”. Можете - тогда она перекроет действие стандартной. Но делать я это настоятельно не рекомендую - это весьма сложное мероприятие.

Имейте также в виду, что код, который Вы привели, работает правильно - так как ему и положено - Вы просто неверно его трактуете. То есть, это - НЕ БАГ И НЕ ОШИБКА.

Окей, не так выразился, не в одну строку (не в смысле переменную), а одной строкой (как в тетради пишут), без абзацев. Но я по прежнему не понимаю:

  1. Зачем нужно именно так?

  2. Чем плохо то, что есть сейчас, с разбивкой на разные строки?

Спасибо. Issue сделал.

Не плохо. Просто Вы считываете в строковую переменную вот тут:

write(' Введите ФИО: '); read(ArrMyType[i].Fio);

и хотите считывать до пробела, а Read считывает до конца строки. Это естественное поведение - Read всё до конца строки считает строкой. После считывания строки надо перейти на следующую строку, поэтому если не заниматься садомазохизмом, то все строки считываются не по Read, а с помощью Readln.

Кроме того - последний ввод:

write(' Введите количество: '); read(ArrMyType[i].Kol);

Вы тут точно хотите ввести это значение и следующий ввод осуществлять с новой строки. Поэтому надо писать Readln:

write(' Введите количество: '); Readln(ArrMyType[i].Kol);