Jump to content

Stefan Glienke

  • Content Count

  • Joined

  • Last visited

  • Days Won


Stefan Glienke last won the day on June 26

Stefan Glienke had the most liked content!

Community Reputation

630 Excellent

Technical Information

  • Delphi-Version
    Delphi 10.1 Berlin

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. Stefan Glienke

    Open Type Arrays?

    Even worse than Variant - you can pass anything to DoSomething now and it simply wont get handled (or raise an exception if you add that as else case)
  2. Did you install the hooks in a way that you don't override any existing hook that might be there already?
  3. Stefan Glienke

    Open Type Arrays?

    Variant will accept everything and their dog which is hardly what is wanted here. @PeterPanettone This is not in any form an array but as @david berneda rightly said a union. See https://en.wikipedia.org/wiki/Union_type We already have such things in Delphi: TVarRec, Variant, TValue. However none of them can be specified to only accept a certain amount of types. If you want something like that then write a custom record type with implicit operators and a TValue as internal storage (saves you from taking care of mixing unmanaged and managed types in a proper way) Just for the lulz: {$APPTYPE CONSOLE} uses SysUtils, Rtti; type Union = record fvalue: TValue; class operator Implicit(const value: string): Union; class operator Implicit(const value: Integer): Union; class operator Implicit(const value: Union): string; class operator Implicit(const value: Union): Integer; function IsType<T>: Boolean; end; procedure DoSomething(const AParam: Union); begin if AParam.IsType<string> then Writeln('string: ', string(AParam)) else if AParam.IsType<Integer> then Writeln('integer: ', IntToStr(AParam)); end; class operator Union.Implicit(const value: Integer): Union; begin Result.fvalue := value; end; class operator Union.Implicit(const value: string): Union; begin Result.fvalue := value; end; class operator Union.Implicit(const value: Union): string; begin Result := value.fvalue.AsString; end; class operator Union.Implicit(const value: Union): Integer; begin Result := value.fvalue.AsInteger; end; function Union.IsType<T>: Boolean; begin Result := fvalue.IsType<T>; end; begin DoSomething(42); DoSomething('Hello world'); end. If you want to go funky then make it a generic type with 2, 3, 4, ... generic type parameters 😉
  4. Stefan Glienke

    Varialbe set to nil

    Thats wrong, only the one that had the [weak] attribute needs to be a Weak<T>. If the reference a weak is pointing to is being destroyed the RTL takes care of making any [weak] marked reference nil. Same does Spring with a Weak<T>. With the pointer that does not happen. So if DoSomethingWithInterface2 happens to be called after TMyClass2 was destroyed (possibly not with this example but a common scenario) with the pointer approach you will run into an AV or other bad things if you dont explicitly set those weak reference back to nil which is why Remy made the dtor which did that - however in real code an object usually does not keep track of all the places it might be weak referenced.
  5. Stefan Glienke

    Varialbe set to nil

    Use Weak<T> from Spring4D in any version before one that supports [weak] if you want proper cleanup of such weak references. Using the pointer approach will not do and you might run into AVs caused by dangling references.
  6. Stefan Glienke

    Should Delphi have native interfaces?

    What you display is known as "default interface methods" in other languages. Java has them and they are in the making for C#8 from what I know. However in both implementations those interfaces can just operate on other interface methods and not force fields of the implementing object - that would be more like scala traits (not exactly sure how they implement that ontop of the JVM)
  7. Stefan Glienke

    One more memory leak and FastMM4

    Solution: Pass TRefCounting.True to AsSingleton because otherwise the container uses a very basic way to determine if the instance is reference counted or not and that is often false if it was implemented by yourself. Explanation: The container needs to know that in order to store the instance served as singleton and properly destroy it in the end: - either by letting go the interface reference if it was reference counted - or calling Free on the object reference if it was not reference counted The issue has been open for a while now and I have a few ideas but it did not make it to the top of my priority list yet: https://bitbucket.org/sglienke/spring4d/issues/237 Alternative solution: If you are using the instance as singleton why implement reference counting in the first place - it makes no sense. By the way: Stop using so many delegates if all you do is resolve all the ctor parameters yourself - that defeats the purpose of using a DI container. If you want to force the DI container to use a certain ctor then put the [Inject] attribute over the ctor- then you will get a resolve exception when it could not provide all parameters. That might be important because by default the container falls back to a less greedy ctor if it cannot provide all parameters (you can configure that behavior) which sometimes lead to defects at it always ultimately falls back to TObject.Create (RTTI cannot see that it might not be visible because information about method overloading is not available) If you want to use a certainly named service to be injected then put the [Inject(<servicename>)] attribute on the specific ctor parameter. Another way would be to use InjectConstructor in the registration and provide the parameternames (at this time you have to specify all parameters - if you want to use the default service then pass TValue.Empty or nil) - I am working on being able to provide value/servicename for individual ctor parameters because that also makes things robust agains refactorings. The code you wrote actually serves no purpose at all - it would be shorter and faster if you used pure DI instead because with all the DelegateTo calls you basically did just that. If you put a parameterless ctor into your DM class which just calls inherited Create(nil); then you can get rid of all DelegateTo calls in your registration and just let the container do its job.
  8. Stefan Glienke

    GExperts supports even more laziness

    @Mahdi Safsafi Oh, yes that's probably inside the debugger that reacts to https://docs.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-debug_event - so one needs to probably go a little deeper there 😉
  9. Stefan Glienke

    GExperts supports even more laziness

    Run the IDE under the debugger - make it show that dialog - pause it and look into the call stack (need to look through several threads to find the correct one) - and eventually you will find it. Then simply hook that call and let it run through your code first. The tricky part is just doing this reliably for all supported versions
  10. Stefan Glienke

    GExperts supports even more laziness

    Hooking into the code that displays this dialog would probably do the job but is probably not trivial. I've had this request long ago when I started TestInsight because if you run your unit tests under the debugger and you obviously also have tests that check if the correct exceptions occur if you do something bad this will result in a lot of exceptions cought by the debugger. In that scenario however it would only not show those exceptions that you expected in your unit test but break on all others which makes it a bit more complex than just "clicking the dialog away"
  11. Stefan Glienke

    FreeAndNil 10.4 vs 10.3.1 and Pointers

    Refactoring away from objects to something else and forgetting FreeAndNil is probably the number one source of defects of this category which is why I am happy for this change in 10.4 even though it also has its quirks most notably an API that tells a lie.
  12. Stefan Glienke

    Your RAD Studio 10.4 Sydney issues

    FWIW - reported as https://quality.embarcadero.com/browse/RSP-29564
  13. Stefan Glienke

    Reproducible AV in Sydney

    Wrong place - report at https://quality.embarcadero.com/
  14. Stefan Glienke


    Print TCriticalSection.InstanceSize and you know if it was fixed or not - spoiler: no, it was not. On Windows that is - on Posix TCriticalSection simply uses System.TMonitor which allocates at least the size of a cache line
  15. Stefan Glienke

    When did Pos become PosEx?

    Delphi XE3 because I have this code in Spring.pas: {$IFNDEF DELPHIXE3_UP} function Pos(const SubStr, Str: UnicodeString; Offset: Integer): Integer; asm jmp PosEx end; {$ENDIF}