Entries in ducktyping (2)


Duck Duck Delphi Release 3

We are pleased to announce the 3rd release of Duck Duck Delphi.  This udpate provides significant changes and enhancements, adding both flexability and power to the framework.

The biggest enhancement is in respect to Interfaces.  Now you can ask if your objects can impersonate an interface, even if it does not implement one.  An object that can impersonate an interface is one that implements all of the interface's methods and properties with compatible signatures.  

For example,

IMath = interface(IInterface)

  function Add(A,B) : integer;

  function Subtract(A, B) : integer;


TMyObject = class(TObject) // does not implement IMath

  function Add(A,B) : integer;

  function Subtract(A, B) : integer;




  obj : TMyObject;

  bOkToAdd : boolean;


  obj := TMyObject.Create;

  bOKToAdd := obj.impersonates<IMath>;






Also new to the framework is simplified access to those interface methods:

if obj.impersonates<IMath> then

  Result := obj.asA<IMath>.add(1,5);



(For those of you who complained that Duck Duck Delphi was less about Duck Typing and more about reflection, perhaps this will help to sway some of those concerns.)

Most of the other changes and fixes have been detailed in our changelog below:


+ Added asA<I> to return a custom variant wrapper around the object allowing it to be called as though it were the interface supplied without using the duck interface methods. allowing you to see if the object has all of the methods and properties required of the interface even if it doesn't implement the interface.
+ Added impersonates<I> check to the object class helper allowing you to see if the object has all of the methods and properties required of the interface even if it doesn't implement the interface.
+ Added several overloads to better support indexed properties
+ Added eachProperty and eachMethod iterators to the TRTTI class.
+ Added selector comparisson functions, equalTo, notEqualTo, moreThan, and lessThan.
+ Added new duck functions to return selectors including: this (the same object via selector), related (all related objects, note that this is the same as "all" used to be), props (all object properties of the object), go (executes a method and returns a selector of the result.
* Altered duck.all to return all related objects as well as any properties of type TObject.
+ Added new selector functions First, Last, Middle, Even, Odd which return new selectors filtered accordingly.
+ Added new selector function "use" which alters the current context of the selector.
+ Added new selector action function "replace" which alters the value of a property only if it matches the value supplied
+ Added new duck procedure "replace" which altersthe value of a property only if it matches the value supplied
* Fixed isa.  It's implementation had gone missing.
* Renamed parameters in TRTTI from ctrl to obj.  ctrl was a holdover from when the class was written to work only on TControl descendants and no longer made sense.
* Changed all methods called "sett" to "setTo" due to Nick Hodges consistent badgering and the overwheming will demonstrated by a very scientific facebook poll.
+ Added new setTo functions on Selector and Duck to allow setting of multiple properties via TPropValue array.
+ Added new asValue class method to TRTTI to simplify convertion to TValue where needed.
+ Started documenting TRTTI class



Duck Duck Delphi

In case you missed it, yesterday we released to open source a new project called Duck Duck Delphi. We are using the code a good deal in our Apesuite refactoring and the new project is actually born from that work.  It is probably the single most useful unit I've ever written and I expect to find myself using it in nearly everything I write from this point forward.  

As a long time Delphi developer, I've always been a huge fan of RTTI.  One of the first internet projects I wrote back in the late 90's involved serializing delphi objects across HTTP to create a remoting api for an ERP application.  It was a great project that taught me a lot about the internals of the Delphi framework and the power you can get from knowing more about your objects at runtime.

In recent years I've had occasion to learn and use Ruby.  While it's true that it's a scripting language, it's beautiful and consistent syntax, language structure and overall architecture really won me over.  I really enjoy Ruby and just how powerful it really is.  It was my first exposure to closures, lambdas and ducktyping... all things that took me some time to wrap my head around, but once it clicked, it was over. How could I ever code without them?

Delphi has since made several advancements making it easier to code in a Ruby-like way.  The biggest IMO was the addition of anonymous methods.  Generics also made it easier to code without knowing a specific type at design-time and Enhanced RTTI made it possible, though extremely cumbersome, to perform some simple ducktyping. Class Helpers and VMTInterceptors made it possible to inject ad intercept functionality of undetermined objects at runtime.

Enter DuckDuckDelphi...

This project aims to take the language enhancements of recent Delphi versions and create an environment that simplifies duck-typing and other Ruby-like coding paradymes within the Delphi world. This project simplifies:


if obj.duck.has('property') and obj.duck.can('dosomething') then


Inline events:

obj.onclick = Event.Notify( procedure(Sender : TObject)




Chained Object Selectors:



duck.all.each(procedure(obj : TObject) begin

This is just the beginning of what you can do with Duck Duck Delphi and only scratching the surface of where we can go with it.  

Please give it a try. Source Code can be found here and if you have questions, please direct them toward our support site.

I certainly hope you find this project as useful as I have and welcome your feedback.