On 10/02/2021 20:17, Ryan Joseph via fpc-pascal wrote:

On Feb 10, 2021, at 11:09 AM, Ryan Joseph <generic...@gmail.com> wrote:

type
TSomeTrait = trait
   public
     parent: TObject;
     procedure DoThis;
end;

procedure TSomeTrait .DoThis;
begin
    // ??? here is our issue. Is this good enough to call the TBaseClass.DoThis?
    TBaseClass(parent).DoThis;
end;
Thinking about this more I don't think there's even a reason for it since Object Pascal 
doesn't let you do stuff like this anyways. If you want to call the super class you need 
to use "inherited" from within the class body.  The example I posted only works 
if there is no virtual/override involved.


Its not about the keyword to be used.
Its not even about the inheritance.

In the example from https://www.php.net/manual/en/language.oop5.traits.php
The trait accesses a method defined in the class to which the trait is applied. (It happens to be from the base class, but that does not matter)

In Pascal that would look like

type
  TSomeTrait = trait
  public
    procedure DoTraitFoo;
  end;

  TSomeClass = class(TObject)
  private
    trait: TSomeTrait; // whatever syntax is used so that the trait is added
  public
    SomeVal: Integer;
    procedure DoSome;
    procedure Dispatch(var message); override;
  end;

procedure TSomeTrait.DoTraitFoo;
begin
  inherited Dispatch(nil); // from TObject
  DispatchStr('');  // from TObject
  DoSome;  // from SomeClass
  SomeVal := 1;  // if we can access methods, then why not data
end;

In the example
|  parent::sayHello();|
"parent" does not refer to the class containing the trait. "parent" = "inherited"

The php example tait's sayHello hides the inherited sayHello => so parent is needed.

So in the example this/self of the embedded trait is the entire object into which it is embedded.

That means also: the trait and the class must be conflictfree even for  private variables. (except where maybe cross unit scoping hides them???)

-----------------
Leaving scoping/conflicts aside.

In Pascal TSomeTrait as it is given above can not compile, as it does not know what DoSome,SomeVal,Dispatch are. Not until it is embedded.
Well it could compile as a generic...

So, if a trait should have such access, then how to make sure the trait can compile?
Maybe:

  TSomeTrait = trait
  imports
// Those must be implement/provided by classes to which the trait is added.
    procedure DoSome;
    SomeVal : integer;
  public
    procedure DoTraitFoo;
  end;

Or (less flexible)
  TSomeTrait = trait
  extends(TSomeClass)  // can extend anything that is inherited from TSomeClass (i.e can access anything that a TSomeClass has)
  public
    procedure DoTraitFoo;
  end;
_______________________________________________
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Reply via email to