Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-devel / 2019-05

modeswitch multihelpers

10 messages · 6 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Ondrej Pokorny

I'd like to thank Ryan & Sven for extending the helpers to be able to handle multiple helpers.

Now I can remove my (obtrusive) helper inheritance

    THelper2 = class helper(THelper1) for TMyObject

very good!

This feature deserves a bold announcement. Now we are only missing Lazarus IDE codetools support for it :)

Again - big thanks.

Ondrej

Reply by email

Ryan Joseph
to Ondrej Pokorny
Show quoted text 13 lines
On May 12, 2019, at 4:03 AM, Ondrej Pokorny wrote: I'd like to thank Ryan & Sven for extending the helpers to be able to handle multiple helpers. Now I can remove my (obtrusive) helper inheritance THelper2 = class helper(THelper1) for TMyObject very good! This feature deserves a bold announcement. Now we are only missing Lazarus IDE codetools support for it :) Again - big thanks.

You’re welcome. I’m looking forward to fixing up some old code myself. :)

Regards,
Ryan Joseph

Reply by email

Stefan Glienke
to Ryan Joseph

I want to argue that the way this is implemented is asking for easily introducing defects into existing code by extending/modifying helpers causing methods to creep into scope. If multiple helpers should be considered they should be treated equally and not by order treating equally named methods as overloads similar to how C# extension methods work.

Show quoted text 27 lines
On 13 May 2019 at 02:25 Ryan Joseph < > wrote: > > On May 12, 2019, at 4:03 AM, Ondrej Pokorny < > wrote: > > I'd like to thank Ryan & Sven for extending the helpers to be able to handle multiple helpers. > > Now I can remove my (obtrusive) helper inheritance > > THelper2 = class helper(THelper1) for TMyObject > > very good! > > This feature deserves a bold announcement. Now we are only missing Lazarus IDE codetools support for it :) > > Again - big thanks. > > > You’re welcome. I’m looking forward to fixing up some old code myself. :) Regards, Ryan Joseph _______________________________________________ fpc-devel maillist - http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

Reply by email

Mattias Gaertner
to Stefan Glienke
I want to argue that the way this is implemented is asking for easily introducing defects into existing code by extending/modifying helpers causing methods to creep into scope.

How can a disabled-by-default modeswitch "defects into existing code"?

Mattias

Reply by email

Stefan Glienke
to Mattias Gaertner

When I wrote "existing code" I was referring to the future when people turn this on for their code and then helpers get changed and not "today existing code".

Show quoted text 15 lines
On 13 May 2019 at 11:45 Mattias Gaertner < > wrote: On Mon, 13 May 2019 11:33:36 +0200 (CEST) Stefan Glienke < > wrote: > > I want to argue that the way this is implemented is asking for easily > introducing defects into existing code by extending/modifying helpers > causing methods to creep into scope. > > > How can a disabled-by-default modeswitch "defects into existing code"? Mattias

Reply by email

Ondrej Pokorny
to Stefan Glienke
Stefan Glienke wrote
When I wrote "existing code" I was referring to the future when people turn this on for their code and then helpers get changed and not "today existing code".

The problem is the same with old style Delphi-like helpers. Multihelpers didn't change much in this regard.

Ondrej

Reply by email

Marcos Douglas B. Santos
to Ondrej Pokorny
AM Ondrej Pokorny wrote 6 lines
On 13.05.2019 11:59, Stefan Glienke wrote: > When I wrote "existing code" I was referring to the future when people turn this on for their code and then helpers get changed and not "today existing code". The problem is the same with old style Delphi-like helpers. Multihelpers didn't change much in this regard.

+1
This is the same as having two functions, with the same signature, in two different units.
Your program will use the first that was found.

regards,
Marcos Douglas

Reply by email

Stefan Glienke
to Marcos Douglas B. Santos

In fact it will use the last one that was found and fwiw this is imo bad and error prone behavior - I guess everyone has had that happen at least once that with some version change or update of some code some clash happened - especially when a routine with the same name but different parameters was introduced somewhere.

I had the impression you are aiming for the best possible solution for a new feature so I brought this up - if you are happy with a "better than before" then please go for it.

Show quoted text 24 lines
On 13 May 2019 at 13:51 "Marcos Douglas B. Santos" < > wrote: On Mon, May 13, 2019 at 7:09 AM Ondrej Pokorny < > wrote: > > > On 13.05.2019 11:59, Stefan Glienke wrote: > > > > > When I wrote "existing code" I was referring to the future when people turn this on for their code and then helpers get changed and not "today existing code". > > > > > > The problem is the same with old style Delphi-like helpers. Multihelpers > didn't change much in this regard. > > > +1 This is the same as having two functions, with the same signature, in two different units. Your program will use the first that was found. regards, Marcos Douglas _______________________________________________ fpc-devel maillist - http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

Reply by email

Ryan Joseph

Sorry I sent the first message to privately but I’m posting this to the list.

Show quoted text 7 lines
On May 13, 2019, at 9:44 AM, Stefan Glienke wrote: Now the author of THelper2 decides that it would be cool if to add a DoThis(msg: string); method. Now what happens to anyone calling DoThis from THelper1? Well if the same rules as with regular methods are applied here then the new DoThis method (not marked as overload) would hide the other one and it becomes uncallable. Yes, you can solve this by still looking if that method does not match - but what happens if multiple helpers add a bunch of DoThis overloads with different parameter types and signatures? There could be a match in the first found helper but actually a better match in a helper that came before (and it might even be that that one was called originally but not anymore now as someone introduced a matching one in another helper). C# extension methods are all treated the same and all as overload not causing any different behavior depending on the order they appear in the using. If you have the case where some call is ambiguous you have to call them as static method (see https://stackoverflow.com/a/8474979/587106).

I see what you mean now (in the example below you can just add “overload” to fix it of course).

It sounds like you want something like "C# style function overloading” as a general feature of the language instead of the “overload” keyword and order of precedence rules that Pascal currently uses. The same problems you’re concerned about could happen with plain functions in different units so I don’t consider this a strictly helper related issue.

Personally I don’t like that approach because it means if an existing unit has a helper (or function) with the same signature the compiler will simply not allow you to overload it. Maybe you could argue for an additional function modifier that says “overload if not ambiguous” so you can be sure adding a new method doesn’t cover some existing method in the same scope.

{$mode objfpc}
{$modeswitch multihelpers}
program test;
type
  THelper1 = class helper for TObject
    procedure DoThis;
  end;
type
  THelper2 = class helper for TObject
    procedure DoThis(msg: string);
  end;
procedure THelper1.DoThis;
begin
  writeln('DoThis');
end;
procedure THelper2.DoThis(msg: string);
begin
  writeln('DoThis:', msg);
end;
var
  obj: TObject;
begin
  obj := TObject.Create;
  obj.DoThis;	// <======== ERROR: Wrong number of parameters specified for call to "DoThis"
end.

Regards,
Ryan Joseph

Reply by email

Sven Barth
to Stefan Glienke: In fact it will use the last one that was found and fwiw this is imo bad and error prone…

Stefan Glienke schrieb am Mo., 13. Mai 2019, 14:54:

Show quoted text 10 lines
In fact it will use the last one that was found and fwiw this is imo bad and error prone behavior - I guess everyone has had that happen at least once that with some version change or update of some code some clash happened - especially when a routine with the same name but different parameters was introduced somewhere. I had the impression you are aiming for the best possible solution for a new feature so I brought this up - if you are happy with a "better than before" then please go for it.

It's in line with how helpers behave already:

Assume you have a class A with a method Foo that you call in your code.

You now add a unit with a helper for A that also has a method Foo. Then the helper's method will be called.

If you now add a second unit with a helper for A with a method Foo then the method of that helper is called.

This behavior is the same no matter if the new modeswitch is used or not. The only difference is if you add a second unit with a helper that does *not* contain a method Foo:

Without the modeswitch the Foo of the original class will be used.

With the modeswitch the Foo of the first helper will be used.

Yes, multiple helpers per type can bite you, but so can a single helper. Helper types are a feature that should be used with care and that best have some IDE support.

Regards,
Sven

Reply by email