Помощь новичкам

Смотря на сколько разнятся версии. В принципе, Вам ничто не мешает переименовать текущую папку, куда установлен PascalABC.NET и сделать новую установку.

Но только следует иметь в виду, что в некоторых случаях программа, написанная на одной сборке, может не пойти без исправления уже на следующем обновлении. Редко, но все же…

Можно

Вообще говоря нельзя, так как PABCRtl.dll один на всю систему. Отключайте запуск с ускорением, чтобы не было конфликтов.

Может быть, нельзя одновременно работать с несколькими версиями? Ведь PABCRtl.dll не устанавливает какой-то процесс, постоянно находящийся в памяти?

Если отключать запуск с ускорением из оболочки, то можно без конфликтов

Известно, что PascalABC.NET реализует ссылочную объектную модель. Как следствие, если X - объект, принадлежащий некоторому классу, то в результате присваивания var Y:=X произойдет копирование ссылки на X в объявленную переменную Y с автовыводом её класса, но при этом X и Y будут ссылаться на один и тот же объект. Это хорошо, потому что просто и наглядно позволяет написать P:=<выражение> и ни о чем не заботиться. Но одновременно это бывает и плохо. Например, если как было указано выше X и Y - это ссылки на один объект, то изменение, сделанное в Х, будет отражаться и в Y, а также, наоборот. Чтобы избежать такой связки, приходится явно выполнять копирование объекта. Так, для массивов имеется функция Copy и мы пишем a:=Copy(b);

А теперь, собственно, проблема. Пусть создается некий класс P

type P=class
   x:array of real;
   y:real;

   constructor(px:array of real; py:real);
   begin
      x:=Copy(px);
      y:=py
   end;

   constructor (n:integer);
   begin
      x:=new real[n];
      y:=0.0
   end;
end;

Я хочу в этом классе иметь возможность делать присваивание вида Q:=P так, чтобы происходило не копирование ссылки, а создавался новый объект, принимающий значения из старого. Конечно, можно написать примерно такой код

begin
  var a:=new P(Arr(1.0,2.0,3.0),-1.0);
  var b:=new P(a.x,a.y);
end.

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

type P=class
  x:array of real;
  y:real;

  constructor(px:array of real; py:real);
  begin
    x:=Copy(px);
    y:=py
    end;

  constructor (n:integer);
  begin
    x:=new real[n];
    y:=0.0
    end;
   
  class procedure operator :=(var pp:P; value:P);
  begin
    pp.x:=Copy(value.x);
    pp.y:=Value.y;
    end; 
end;

begin
  var a:=new P(Arr(1.0,2.0,3.0),-1.0);
  var b:=new P(a.x,a.y);
end.

Компилятор ругается на строку var a:=new P(Arr(1.0,2.0,3.0),-1.0); - пишет “Несколько подпрограмм могут быть вызваны”.

Хотелось бы увидеть решение, если оно возможно.

Нет, семантику присваивания менять нельзя. То есть, ссылочное всегда останется ссылочным. Оператор := как в C++ тоже перегружать нельзя. Сакрального знания нет.

напиши функцию clone, делов то?

function clone:= new P(self.x,self.y);

Я не задавал вопроса, как это обойти. Меня интересовало конкретно, можно перегрузить операцию присваивания, или нет. Непонятно было, что можно перегрузить +=, но нельзя :=

:= имеет особый смысл для размерных и ссылочных типов. Нельзя. И в C# нельзя

Спасибо, я понял. Сбила с толку “Справка”.

Перегружать можно все операции за исключением @ (взятие адреса), as, is, new. Кроме того, можно перегружать специальные бинарные операции +=, -=, *=, /=, не возвращающие значений.

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

@, not, ^, +, - (унарные), new *, /, div, mod, and, shl, shr, as, is +, - (бинарные), or, xor =, <>, <, >, <=, >=, in ?:

А то я планирую делать реализацию векторов и матриц для линейной алгебры и думаю перегружать операции, в частности, хочу для скалярного произведения взять *, а для векторного думаю про and

Всё можно. Нельзя ?: new as is := не операция!!!

А ведь и правда…это оператор! А у меня на ^ ругалось… хотел его выбрать для векторного произведения вначале.

оператор := перегружать можно

Ох… а почему тогда не работает код в этом сообщении?

Опишите operator:= как функцию. И P лучше записью сделать (в сущности для этого перегрузка и предназначена). Иначе не получится объект pp.

Спасибо, понял. Попробую…

function GetTArr<T>(c:integer) := new T[c];

пару недель нашёл такого типа функцию где то в system или PABCSystem, в общем где то… попробовал сам - действительно компилятор принимает, но как её надо вызывать? ещё при описании всплывает логический вопрос “откуда паскаль узнает что за тип T?” и при вызове GetTArr(5); или даже var a:array of integer := GetTArr(5); выскакивает соответствующая ошибка… так как же это можно вызывать?

P.S. нашёл! PABCSystem строка 10466:

function GetRuntimeSize<T>: integer;
var val: T;
begin
  result := System.Runtime.InteropServices.Marshal.SizeOf(val);
end;

просто так использовать как и мою GetTArr не получается

Попробуйте так: var a:= GetTArr&<integer>(5);

Пусть проектируется некий модуль, содержимое которого пользователь впоследствии не сможет менять. Модуль вызывается из пользовательской программы и получает от нее набор параметров, в том числе и имя некоторой процедуры или функции, также определяемой пользователем.

Вызов может иметь вид A(p1,p2,p3,f(x,y,z,…),p4,…), т.е. количество и тип параметров вызова А определяется интерфейсом модуля. Функция (или процедура) f может вызываться непосредственно из пользовательской программы и тут все понятно: вызов организует пользователь. Но она также должна передаваться на любую глубину вызова и внутри модуля. Если это некая f(x), то тут все понятно, потому что интерфейс функции известен. Но если интерфейс может меняться (например, меняется тип и количество параметров, то как тут поступить? params предполагает передачу переменного числа параметров но в виде массива из однотипных элементов. А если аргументами являются переменные разных типов, часть параметров - это вообще массивы… Конечно, совсем ничего не знать об интерфейсе внутри модуля - так не бывает, поскольку тогда непонятно, что с этой функцией делать. У меня есть мысль реализовать функцию, как объект некоего класса и передать в качестве параметров ссылку на такой объект. Но для этого пользователь должен уметь работать с классами. А нет ли более простого решения? Хочется, чтобы как в Фортране (например) было - передаем в списке только имя функции f, но её интерфейс не расписываем, поскольку он пока что неизвестен. Вариант type=function f(…) мне не представляется удачным: такой тип нельзя определить при создании модуля все по той же причине неконкретности интерфейса на момент написания модуля.