I love IEnumerable (the Spring4D one, not the System.pas one ^^) and "record" helpers.

I love IEnumerable (the Spring4D one, not the System.pas one ^^) and "record" helpers.

Instead of writing a loop over the array returned from TRttiType.GetMethods figuring out those with the most arguments on the most derived class that match the passed arguments I could just chain Ordered, TakeWhile and Where for some badass "query" that returns the constructor(s) I want.

How that is possible? Check this out:

uses
  Spring.Collections,
  Rtti;

type
  TRttiMethodArrayHelper = record helper for TArray
    function AsEnumerable: IEnumerable;
  end;

function TRttiMethodArrayHelper.AsEnumerable: IEnumerable;
begin
  Result := TCollections.Query(Self);
end;

Comments

  1. Would you mind sharing the Ordered, TakeWhile and Where bits perhaps, please?

    I'm not sure what I'm seeing (or should be seeing.) I haven't used S4D's collections and don't understand the significance of the code you posted.

    ReplyDelete
  2. You can see it here (in the method SelectEligibleConstructor): https://bitbucket.org/sglienke/spring4d/src/0f2d892b966cf8ee854793c4ddfe1055a7b0a0b0/Source/Core/Container/Spring.Container.ActivatorExtension.pas?at=feature/container-refactoring

    Though in that code I already have an IEnumerable but with the code I posted above you can turn any TArray into an IEnumerable and then do all kinds of operations on them without looping with conditions and stuff yourself. Just focus on set operations.

    ReplyDelete
  3. Interesting.  I like the flow of code there - but don't you find the anonymous methods almost unreadable?  There are three methods squashed into those last 25 lines of code, and I can't "scan" to see which parts of code are part of an anonymous method and which are part of the logic of the parent method.

    ReplyDelete
  4. David Millington I agree that it does not seem very readable for the "untrained" eye. If you work often with these types and anonymous methods you find it less cumbersome to read and write imo.
    However the verbose syntax of anonymous methods in Delphi does not make it very appealing to use them. So if we could get a nicer syntax (or even lambda support) that would be a huge benefit.
    Also the extra construction of a comparer to wrap the anonymous method is unnecessary (I did not overload these methods to directly provide the anonymous method and do the wrapping inside). That is because I did not want to blow up the class even more by providing numerous overloads for everything. Interface helpers that also work on generic types would be a great benefit here because the basic IEnumerable in fact would only need a handful of methods and everything like Ordered, TakeWhile or Where would be implemented on a helper. That would keep the interface and any implementing classes very slim.

    ReplyDelete
  5. I gave up on trying to "linq-ify" delphi collections because I do find the readability is below the acceptable level. Until EMBT comes up with type inference and lambdas it's not worth it.

    ReplyDelete
  6. Alexandru Ciobanu That is because you tried to much imho.
    Current state of collections in Spring4D is a reasonable compromise between usability and readability on the one hand and feature richness on the other. I tried a similar approach to your enex that would have improved the list of features (in fact all "extension methods" even those that cannot be part of an interface because being parameterized). The problem with that was that it forced all dependencies on your type due to using generics. Compiletime and binary size both skyrocketed.

    ReplyDelete
  7. You are probably right about trying too much :) But on the other hand, after enjoying these features in C# for years It's very hard to accept anything less (well, a lot less). My opinion about most people I worked with is that - a feature is either easy to use or not useful at all.

    ReplyDelete
  8. Alexandru Ciobanu I could not agree more.

    ReplyDelete

Post a Comment