Is there anyway to use the property like behavior?
Asked Answered
A

3

-2

I have the following formula

X := X + F*(1-i div n);

Where

X, F, i, n: integer;

The code I'm using is this

F := 7; // the initial speed with no friction.
n := 10; // the animation number of steps.
Hn := n * 2 ; 
X := 0;  // first Pos
i := 1;  
J := 1;
while J < Hn do
begin
  X := X + F * (1 - i div n);
  if X > Xmax then X := 0;  <-- line (1).
  if i >= n then Dec(i)
  else Inc(i);
  Inc(J); 
end;

If it was possible I would like to use this but without class/record implementation(not inside a class/record implementation/method).not the exact syntax, just the same principle, instead of direct assignment to X the SetX is called then the result is assigned to X.

X: integer write SetX; // This is not a correct delphi syntax. I added it to explain the behavior I want. 

function SetX(aValue: integer): integer;
const
  Xmax: SomeIntegerValue;
begin
  if aValue > Xmax then result := 0  
  else result := aValue; 
end;

So I could omit Line (1). If this was possible, all the lines after the formula would be omitted and the while loop would look like this

while J < Hn do  // J will be incremented each time the loop wants to read it.    
begin
  X := X + F * (1 - i div n);
end;

Is there anyway to use the property like behavior?

Note: I'm looking for a way to alter the assignment and reading ways of a variable like you do in a property of a record/class.

Acker answered 30/10, 2017 at 17:43 Comment(5)
I would use IfThen here.Lounge
You will still be able to right just X := X + F * (1 - i div n); if your loop is also inside a record method, I think that is the best way to implement this.Gabriella
I'm not sure what you mean by universal, you will still need to put it in some procedure. The only difference that you will have in your code is that instead of calling it like MyProcedure you will write MyRecord.MyProcedure. Everything else will be the same.Gabriella
@Gabriella I know this (read my first comment or the second note). and I think I explained universal in my last comment too.Acker
Program into the language. You are swimming against the current. Don't. Use a local function. It will be more explicit and clear anyway. It's a better solution.Distemper
D
2

Is there anyway to use the property like approach outside a class/record?

No, property getters and setters can only be implemented in records and classes.

Distemper answered 31/10, 2017 at 4:25 Comment(6)
David, I know this. I'm asking if there is any way to have the same output (using assembly or any other way to alter how that variable X is assigned and read)Acker
I understand your question. The answer is no. End of story.Distemper
David. please see my answer. I would like to know your opinion on this. thanks for your help.Acker
David, pardon me, but I'm not a native english speaker. does that appalled word mean shocked in a good way :).Acker
No, I mean shocked in a bad way. That is a quite monstrous abuse of the language.Distemper
I agree with you. I just wanted to guarantee that overloading the := is not possible even if I abuse the language. The result was shocking indeed.Acker
G
0

You can use local function like

procedure YourProcedure;

var
  X: Integer;
  LJ: Integer;
function J: Integer;
begin
  Inc(LJ);
  Result := LJ;
end; 
procedure SetX(const AValue: Integer);
const
  Xmax: SomeIntegerValue;
begin
  if aValue > Xmax then X := 0  
  else X := aValue; 
end;
//...
begin
  while J < Hn do  // J will be incremented each time the loop wants to  read it.    
  begin
     SetX(X + F * (1 - i div n));
  end
end.
Gabriella answered 30/10, 2017 at 18:0 Comment(2)
LJ must be initialized explicitly prior the first call of J. Unfortunately this ruins the beauty and expediency of this aproach.Simony
Eugenek, please see my answer.Acker
A
0

I found a way to do what I wanted. I know that overloading the := operator is not possible, However forcing the compiler to produce the same behavior as the overloaded operator would behave is possible.

The overloading would not let me control the LSA (Left Side Argument). but it gave full control to implicitly convert any TType (in my case it is an integer) to TXinteger. So all I had to do is make sure that every operator would result in a TType which will force the compiler to implicitly convert that to a TXinteger.

Forcing the compiler to use my implicit operator every time it wants to assign something to TXinteger means I control the assignment Hence I overloaded the := operator.

the following is a test example that makes omitting Line(1) possible.

program Project4;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils;



type
   TXinteger = record
     X: integer;
     class operator Add(a, b: TXinteger): integer;
     class operator Add(a: TXinteger; b:integer): integer;
     class operator Add(a: integer; b:TXinteger): integer;
     class operator Implicit(a: Integer): TXinteger;
     class operator Implicit(a: TXinteger): Integer;
   end;

// Example implementation of Add
class operator TXinteger.Add(a, b: TXinteger): integer;
begin
  result := a.X + b.X;
end;(**)

class operator TXinteger.Add(a: TXinteger; b:integer): integer;
begin
  result := a.X + b;
end;

class operator TXinteger.Add(a: integer; b:TXinteger): integer;
begin
  result := a + b.X;
end;

class operator TXinteger.Implicit(a: Integer): TXinteger;
const
  Xmax: integer = 10;
begin
  if a > Xmax then result.X := 0 else result.X := a;
end;

class operator TXinteger.Implicit(a: TXinteger): Integer;
begin
  result := a.X;
end;

var
X: TXinteger;
Hn, F, i,J, n: integer;
begin
  try
  F := 7;
  n := 10;
  Hn := n * 2 ;
  X := 0;
  i := 1;
  J := 1;
  while J < Hn do
    begin
    X := X + F * (1 - i div n);
    // Line (1)  is gone now.
    if i >= n then Dec(i)
    else Inc(i);
    Inc(J);
    end;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

Note: for this case it is pointless to do all of this just to omit one line of code. I wanted to share this because it gives an idea of how one could overload the := operator.

What I wanted is this:

  • Alter how X:Integer is read (value read from the variable x's storage).
  • Alter how X:Integer is assigned.

by overloading all the operators that use the value of X, I completed the first. And by forcing the compiler as explained above, I completed the second.

Thank you all for your help.

Acker answered 16/11, 2017 at 2:37 Comment(4)
If I understand the question correct, it wants a solution without any "class/record implementation". This code, however, uses an assignment to a record variable and thus fails to satisfy the requirement in the question.Fighterbomber
@SertacAkyuz without any "class/record implementation" means (to me at least). not inside a record/class implementation/method.Acker
I saw the edit, the answer still fails to satisfy requirements, operator overloading methods still belong to that record.Fighterbomber
@SertacAkyuz Then my decision to not accept it as an answer is correct. It was the only thing I found that would do the job.Acker

© 2022 - 2024 — McMap. All rights reserved.