Jump to content

Leaderboard


Popular Content

Showing content with the highest reputation on 07/14/20 in all areas

  1. Edwin Yip

    Open Type Arrays?

    As @Stefan Glienke has pointed out, we have TVarRec, Variant and TValue to deal with situation of: The type of the parameter is uncertain But in addition to the above situation, open array parameters are designed to deal with even more complex situation: Both the types and number of parameters are uncertain. The most well-known case is the Format function. However, I think the OP is heading to a wrong direction to use open array parameters for simplifying the example code he's given. There is at least one better solution: procedure DoSomething(const AParam: string); overload; begin // procedure body here end; procedure DoSomething(const AParam: Integer); overload; begin DoSomething(IntToStr(aParam)); end; The overloaded procedures eliminate the use of the `if` statement and make the code simpler and easier to read. Just my 2 cents. Edit 1: Please note, 'less lines of code' <> simple, 'more lines of code' <> complexity Edit 2: One more benefit of my above alternative method - More user friendly to the clients (that uses the DoSomething procedures). Because the clients can see exactly the type of the parameters to provide, and this is exactly the advantage of statically typed languages over dynamically typed languages such as JS .
  2. David Heffernan

    Open Type Arrays?

    In the OP you also write an implementation for each different type. So where is the saving?
  3. Cristian Peța

    Open Type Arrays?

    Depends. I added only 15K LOC last year to my project. A lot of time I spend thinking how to add features asked by customers to actual app logic. This doesn't have to do with old code but to old app logic and not to break old behavior. An to leave space for feature improvements because this is a 20 years old project.
  4. Vincent Parrett

    Open Type Arrays?

    This all seems like an over complication for little gain. Perhaps the OP could explain better what he is trying to achieve by this? As @David Heffernan said, this is worse than method overloading, and the need for that could be removed in many cases by allowing named parameter passing. IMHO, most uses of GetTypeKind in generic code is just making up for the lack of constraint types on delphi's generics.
  5. 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 😉
  6. Uwe Raabe

    Open Type Arrays?

    And copy the method body in each? Well, it could split that code and put the pieces into the appropriate overload. On the other hand, that is exactly what a developer would do - and that is way more readable and maintainable (at least IMHO).
  7. Cristian Peța

    Open Type Arrays?

    For this case will work with Variant. procedure DoSomething(const AParam: Variant); begin ShowMessage(AParam); end;
  8. I my last GExperts related blog post I wrote about the new “Close Exception Notification” expert which I just had added to GExperts. It was a hack that hooked the Exception Notification dialog. This spawned a discussion in the international Delphi Praxis forum and resulted in a rewrite of the expert. It’s now called “Filter Exception” expert and instead of hooking the dialog it directly hooks into the code that shows this dialog. Thus it prevents the dialog from being shown for filtered exceptions. Read on in the blog post.
  9. 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;
  10. David Heffernan

    FreeAndNil or NilAndFree ?

    Nothing can save you at this point.
  11. 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.
  12. David Heffernan

    FreeAndNil or NilAndFree ?

    Destructors must not raise exceptions. My personal view is that if they do then the best course of action is to terminate the process.
  13. 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
  14. esegece

    ANN: sgcWebSockets 4.4.1

    Hi, All other components support iOS, as Android, Windows, OSX, Linux, Lazarus... the only one which doesn't support is Telegram client component. Thanks for letting me know. Kind regards, Sergio
  15. Lars Fosdal

    Open Type Arrays?

    I am trying to see a proper use case for this, as the example is too simplistic to make sense. What is the problem that needs to be solved? What is the duplicate work that needs to be eliminated?
  16. santiago

    Ctrl Tab Ide Plugin

    Issue has been solved. 🙂
  17. 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)
  18. David Heffernan

    Open Type Arrays?

    This seems worse than method overloading to me. There you have compile time branching. Here you have to perform runtime type checking.
  19. Stuart Clennett

    Handling MultipartFormData

    @alejandro The demo does not save the file at all. You are required to implement that. However it is quite simple. For example, in the `StoreDataAndFile` method in `Server.Resources.pas` you could use a memory stream to access the Bytes and save to a file if SameText(LParam.FieldName, 'image') and LParam.IsFile then begin Result.FileSize := Length(LParam.AsFile.Bytes); Result.FileName := LParam.AsFile.FileName; // This will save the file lStream := TMemoryStream.Create; try lStream.Write(LParam.AsFile.Bytes, Length(LParam.AsFile.Bytes)); lStream.SaveToFile(TPath.Combine(C_RootPath, TPath.GetFileName(LParam.AsFile.FileName))); finally lStream.free; end; end In this instance, `C_RootPath` is just a folder on the server where uploaded files should be saved, but you could make this dynamic based on user info in the Token for example. Hope this helps
×