Jump to content

Stefan Glienke

Members
  • Content Count

    1430
  • Joined

  • Last visited

  • Days Won

    142

Everything posted by Stefan Glienke

  1. Stefan Glienke

    Are we just "Cash Cows"?

    Will probably be reclassified as "new feature" :trollface:
  2. Stefan Glienke

    Help with string extraction function

    For parsing purposes it might not be a good idea actually to return a string as that causes heap allocation every time you extract a substring (*) which I would guess does not only happen once but many times. Something like a PChar with additional Length information might be a better fit. If you really need the text as new string entity you can still materialize it. (*) You will just not notice in your benchmark because in the loop the same string instance is being reused all the time - but if you would run this in 10.4 story might be different (see my comment in https://quality.embarcadero.com/browse/RSP-29450)
  3. Stefan Glienke

    Open Type Arrays?

    Yes, because 1 is not Integer
  4. Stefan Glienke

    Open Type Arrays?

    If we just could write class operator Implicit<T>(const value: T): TValue; ... oh wait... we can! type TValueHelper = record helper for TValue class function &&op_Implicit<T>(const value: T): TValue; static; end; class function TValueHelper.&&op_Implicit<T>(const value: T): TValue; begin TValue.Make(@value, System.TypeInfo(T), Result); end;
  5. Stefan Glienke

    FreeAndNil or NilAndFree ?

    FreeAndNil is correct from the consumer point of view - you call the routine it frees the thing and then once it returns you have a nil reference. That it sets the reference to nil before it actually calls Free is an implementation detail to protect against potentially recursive attempts to FreeAndNil the same reference or accessing an object which is undergoing destruction and probably a result of the convoluted architecture of TComponent and Co.
  6. Stefan Glienke

    Open Type Arrays?

    No - Anything is an untyped var parameter - if you put such a signature into an interface with methodinfo on you even get a funky compiler error E2134 Type '<void>' has no type info
  7. Stefan Glienke

    Open Type Arrays?

    Then make it do a strict type check comparing with TValue.TypeInfo... also method overloading and distinct types is a source of errors in itself because they are always assignment compatible with their base type so that does not count as argument. I can also pass a TFileName, a TCaption or whatever to your DoSomething2 and it will happily go into the string overload. BTT if Delphi was more functional I could very well see more usecases for this in the form of monads like the maybe or either type because they can very well solve a lot of unnecessary cyclomatic complexity
  8. 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)
  9. Did you install the hooks in a way that you don't override any existing hook that might be there already?
  10. 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 😉
  11. 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.
  12. 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.
  13. 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)
  14. 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.
  15. 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 😉
  16. 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
  17. 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"
  18. 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.
  19. Stefan Glienke

    Your RAD Studio 10.4 Sydney issues

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

    Reproducible AV in Sydney

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

    TFixedCriticalSection

    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
  22. 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}
  23. Sorry to disappoint you but that does not compile but raises [dcc32 Error] E2574 Instantiated type can not be used for TYPE'd type declaration Too bad we are working with Delphi where it does not matter because I can still assign a TUserName to TUserFirstName
  24. Stefan Glienke

    Should Delphi have native interfaces?

    Yeah sure... Good luck with that - there are tons of more frequently asked and easier to design and implement features open for years. I am very certain that Bruneau had the C++ approach in his mind even though he mentioned .NET/Java (which have GC that Delphi does not have) because otherwise memory management would clash. And if I am not totally mistaken after a bit of search you cannot even implement more than one interface per class in C++ - but again my practical C++ experience is many years ago. Now C# and Java can implement multiple interfaces per class and under the hood interfaces are basically the same as classes just that you cannot instantiate them. But the compiler and the runtime know about all that - if you think Embarcadero can pull this off you must be new to the game.
  25. Stefan Glienke

    Should Delphi have native interfaces?

    There is no proposal - there is just a "it would be cool if" without any actual suggestions how something can be achieved. I asked a couple of questions but they have not been answered (or I missed those) that are important to decide if something like event<->interface method binding can be achieved and how it would look like. Currently any assignment of interface methods to an event would break reference counting similar to how anonymous methods can't be assigned to an event. One is a managed type, the other is a record with 2 raw pointers. Now we could all list stuff that would be cool to have without actually evaluating if that is technically possible - but to me that would be just a waste of time I could spend more productive.
×