A few cobwebs, but looks like everything’s still working! Can’t promise a lot more to come, but I have one or two things lined up…
I’ve just noticed RemObjects have released a new Oxygene version together with ‘RemObjects C#’, a C# sister product that was codenamed Hydrogene – check out the announcement here. The improved cross platform support sounds interesting (traditionally, the Oxygene language would differ somewhat depending on the target platform), and in the case of RemObjects C#… well, it seems a competitor is a bit rattled!
Dearie me – read that and you would never guess that when it comes to targeting Android, Delphi and Xamarin are on one side of the fence and Oxygene and RemObjects C# the other, for better or for worse…
And now we get this…
At least Delphi has done generics on OS X since 2011 😉
So… I was finally broken: I created a StackOverflow account. Annoyingly, a certain individual in particular is waaaayy too fast in answering most Delphi questions (genuine expertise + quick on the button = cheating, surely?)… so I started picking off Access ones instead (easy points there – write three lines of trivial SQL, and bingo). Alas, but even for a subject area in which one would expect to find a fair few novices asking novice questions, there remains a certain… priggishness about the fact.
(Actual picture of self-appointed SO
[PS: to the literal-minded, no I don’t actually think David is a ‘cheat’ any more than I think Eric Cartman actually patrols StackOverflow 😉 ]
Honestly, for how many versions now has the following got through?
unit FMX.Types; //... type TGradientPoint = class(TCollectionItem) private FColor: TAlphaColor; FOffset: Single; function GetColor: TAlphaColor; procedure SetColor(const Value: TAlphaColor); public procedure Assign(Source: TPersistent); override; property IntColor: TAlphaColor read FColor write FColor; published property Color: TAlphaColor read GetColor write SetColor; property Offset: Single read FOffset write FOffset nodefault; end; //... procedure TGradientPoint.Assign(Source: TPersistent); begin if Source is TGradientPoint then begin FColor := TGradientPoint(Source).FColor; FOffset := TGradientPoint(Source).FOffset; end else inherited; end; function TGradientPoint.GetColor: TAlphaColor; begin Result := FColor; end; procedure TGradientPoint.SetColor(const Value: TAlphaColor); begin FColor := Value; end;
What am I whinging about you say? This:
- What’s with the weird IntColor/Color duplication? Probably an historical thing… but why wasn’t the IntColor version taken out when the Color version was refactored?
- Why does Color have a getter that just directly returns the value of the backing field?
- Why doesn’t its setter (and Assign) call the Changed method?
- Where’s the Add method for TGradientPoints to cast the TCollection implementation’s result to TGradientPoint?
- Where’s the Update override for TGradientPoints? We want a property change to make a visible difference, right?
Oh, and don’t get me started on how the TGradient property editor is both horrible to use and set up to replace (not complement) what would have been perfectly reasonable default Object Inspector behaviour…
Arnaud Bouchez of Synopse open source fame (mORmot etc.) has written an interesting piece on the ‘nextgen’ compiler that debuted with XE4’s iOS support – check it out.
Back last July, I blogged about terrible example code posted by Stephen Ball, an Embarcadero ‘Product Evangelist’. Ultimately, the critique of Ball’s code was really just a lead-off for pointing out how the same anti-pattern used had appeared prominently in the FMX source too. Happily, XE3 RTM saw most of that removed (though not all of it). However, for reasons I don’t understand, Ball has now proudly turned his blog post into a YouTube video:
Honestly, view it and weep. I expect his defence will be ‘but I’m only illustrating class helpers’, but if so, that would be dubious given he’s already been warned the example makes him look foolish [on his original post, the automated pingback from my blog was accepted, but my actual comment – ‘I’ve just posted a critical (but friendly) commentary here’ – never got past the moderation queue. His reply implied he still read it though]. Moreover, it’s perfectly possible to demonstrate class helpers without writing rubbish – check out the relevant page on Lachlan Gemmell’s TIndex for examples. (*)
That said, the class helper anti-example wasn’t the first time Ball had put out poor code – if you want something just as bad, check out his ‘white paper’ on packaging a FMX form into a DLL or dylib, which was also something he originally put out in the XE2 timeframe and has now recently re-promoted. The example used in it is an image file picker, which is fair enough, but here’s how he writes his exports:
function SelectPicture(AFolder : PChar): PChar; cdecl; var ResultStr : string; Temp: PWideChar; begin ResultStr := ''; try ResultStr := TfrmImages.SelectPicture(AFolder); finally Result := StrAlloc(Length(ResultStr)); Temp := Addr(ResultStr); StrCopy(Result,Temp); end; end; procedure DisposePicture(SelectPictureResult : PChar); cdecl; begin StrDispose(SelectPictureResult); end;
If that doesn’t embody the mentality of ‘It compiles, so ship it!’, I don’t know what does.
(*) PS – the David Glassborow articles linked to on the TIndex are now found here and here – I’ve posted the corrections to the TIndex blog, so hopefully the links might even be fixed by the time you read this post.
PPS – eh?