Learn about Multi-Tier Application Development with DataSnap XE

Embarcadero has just published my new DataSnap white paper where you learn about Multi-Tier Application Development with DataSnap in RAD Studio XE, based on a small but real-world DataSnap application that covers just about everything you can imagine: from secure connections to simple server methods, server methods returning read-only datasets, datasetproviders returning master-detail datasets, with autoincrement primary keys (and how to handle those), using authentication and role based authorisation to secure not only the server methods but also the exposed datasetproviders, deployment and more.
Read More

Flotsam and Jetsam #23

Do you have TestComplete skills?  Do you know someone who has TestComplete skills? If so, we want to hire you. (Well, we don't necessarily want to hire you if you merely know someone with TestComplete skills, but you get the idea.  ) StackOverflow Question of the Week:  What are the pros and cons of using interfaces in Delphi? Lot’s of good discussion and some nice answers. THTMLWriter Update: I have finished and checked changes to fully support the <table> tag and its subordinate tags, including ensuring that they aren’t used out of order.  I have but three tags left (<dd>, <dl>, <dt>), and then I think I will be “done” in that I’ll declare it to be a “1.0” release.  At that point I’ll “freeze” the interface and won’t make any more changes to it.  Any subsequent additions will require a new interface at that point.  Your feedback gratefully accepted.  In addition, the IHTMLWriter interface now descends from ILoadSave to remove the duplication. I hereby officially declare Hodges’ Law: “The first person in an argument to compare the software development process to building automobiles loses that argument.” Danny Thorpe pointed me to this interesting article talking about using existing Wi-Fi connections to expand the coverage of a given network.  I’ve often wondered about this – that is, why don’t cell networks make it easy for people to expand their networks?  I’d be willing to bet that if you go to the mall, the Sprint Store (or the Verizon store, or the AT&T Store or the T-Mobile store) all have some sort of repeater or other type of device that ensure that their store has a five-bar signal.  (Who would buy a phone at the store where there is a weak phone signal?)   Why not put those all over the place?  Why not install them in office buildings, malls, airports, etc., where people are? Why not sell them (give them) to people to install in their homes?  Or why not make the phone able to call over any given WiFi network, allowing the phone to work even where there is no cell tower at all?  It seems to me that this is an unexplored and unexploited feature for cell network providers, and something that could drastically increase the already high value of a cell phone. Heck, I’d be willing to share some of my bandwidth with my neighbors to increase and improve the coverage in my neighborhood. Another great argument about why unit-testing is so cool and powerful from Uncle Bob.
Read More

Flotsam and Jetsam #20

My Dad got me this clock for Christmas and I now have it hanging on my wall at the office here at the World-wide Headquarters of Gateway Ticketing.  It is definitely an eye catcher and a conversation starter.  I was able to figure out some of the numbers (12, 6, 7, 8, and 11), but the rest I had to get from a blog post that explains them all.  I happy and honored to say that the Delphi Feed for my blog is now part of DelphiFeeds. Hopefully this will mean that these amazing pearls of wisdom will benefit a broader audience than just you fine people. We here at Gateway are in the process of migrating to Mercurial for our source control (I’ve probably mentioned that before….) and we are considering using bitbucket.org to host our repository.  Thus, I’ve created a small Delphi project there called DelphiClean. It’s not much right now, but it is serving the purpose of letting me see how things work on BitBucket.  I will update it in the future, particularly with the ability to provide a custom list of extensions to be “cleaned”. Now that Delphi has cool language features like Generics and Anonymous Methods, there is a lot of very cool code being written. Combine that with the ease of sharing code on places like GoogleCode, BitBucket, SourceForge, etc., and it ‘s a pretty cool time to be a developer.  The indefatigable Alex Ciobanu is a guy who is producing some amazing code.  Alex create the DeHL project, and now he’s created out of that a project called Collections.  Well worth a look.  The fun part is that Alex creates a full suite of unit tests for his code, so you can use it with confidence, and if you find a bug, you can write a failing unit test for him, and he can fix it, incorporate the now passing test, and we’ll all know if that bug appears again.  (There’s my daily pitch for unit testing….) In any event, Alex’s code is quite remarkable, and he’s a valuable member of the Delphi RTL team.  Here’s hoping some of this great code finds its way into the RTL. Danny Magin posts about the Developer Solutions Conference.  I wish I could go – alas, duty calls – but you can. (I’m particularly interested in the Android development stuff.  Alas)  Plus, it’s in Vegas, baby!
Read More

The future of C#, the bloat explosion, and what happened instead

Looking back on this video with Anders Hejlsberg, about the future of C#, from march 2009, or this blog post about the upcoming bloat explosion, seems quite awkward with the current explosion of iOS and especially Android. There are numerous awkward parts in the video: The focus on objects, the "huge amounts" of memory and the statement that multithreading is the exception. As readers of this
Read More

Android sells better than Windows to consumers

If you combine a few news articles, things get interesting: http://www.guardian.co.uk/technology/2010/nov/29/apple-ipad-cannibalising-pc-sales "Gartner forecasts that worldwide PC shipments for 2011 will reach 409m units" = 1.1 million per day. It is fair to expect less than 40% of these sales to be for consumers. This is an 18% growth, meaning that in 2010, we can expect PC sales to reach 138
Read More

R.I.P Microsoft Windows?

Microsoft is usually very good at presenting new products years ahead of the actual launch - but there continues to be a very remarkable absence of a single strategy for support of Windows applications or Windows as a well integrated desktop. Android provides many improvements that Windows does not offer as part of the standard platform: * Easy app discovery and installation (Android Market) *
Read More

Non-Delphi: Postmodernism, Transformers: ROTF and Baudrillard

The simulacrum is never that which conceals the truth--it is the truth which conceals that there is none. The simulacrum is true. (Baudrillard, Simulacra and Simulation) I've just watched Transformers: Revenge of the Fallen, and it got me thinking. It's perhaps the most post-modern movie I've seen to date. T:ROTF isn't so much a movie as a string of soundbites, stereotypes and cliches arranged into a 2.5 hour trailer for a movie you'll never get to see, because it was never made. You turn up for the product the advertisement is selling, but it turns out the whole product was ad. There's no "there" there. I've never seen a better embodiment of Baudrillard's conception of simulacrum than this. The meaningless symbols are so densely packed in this movie I need a convention. Everything in the movie is a stereotype or cliche: a stand-in, an intellectually lazy shorthand reference. I'll be lazy too, and mark stereotypes in my commentary with [brackets]. The beginning is indistinguishable from a trailer. A brief [dawn of man] scene, you know the kind, [stone age people silhouetted against a dawn sky somewhere in Africa], doing [caveman things with the spears and the facepaint], with a [rumbling voiceover] helpfully telling you that it's ["Earth, birthplace of the human race"]. If it were storytelling, it would be rushed, heavy-handed, and contemptuous of the viewer - both showing and telling. But I don't think it is storytelling. It's arranging some symbols (humans, decepticons) into a particular aspect required for later symbolic purposes. The decepticons portrayed in this ancient time are [evil] (with [King Kong-like grabbing] of a feeble human, albeit male), but there is no motive, no narrative. Why would such powerful machines pay any more attention to stone age humans than they would apes, or insects, which they can swat away with similar ease? Next up: Shanghai, [disaster scene], with [disaster radio news chatter]. Cue [Pentagon command centre], explaining that some black hawks are moving in, while showing some black hawks moving in: Americans aircraft and troops entering Chinese territory, in complete suspension of geopolitical disbelief, no explanation considered necessary. Expository trailer voiceover says "new autobots", while expository camera shot shows new autobots, including [hot girl on bike], [fast car], and [military transport]. "Together, we form an alliance", explains voiceover, while showing human troops in [military transport] (which subsequently transforms). No attempt to explain why squishy soldiers with small arms are going up against fast-moving heavy machinery. What do they hope to achieve with their flying pieces of lead? Would they go up against even a human-engineered tank with such miserable munitions? Nor an explanation for the gunships flying with mere tens of feet clearance from the ground and the surrounding buildings that tower over them, completely negating the tactical advantages of a mobile, hovering cannon and missile platform. But all is soon revealed. The squishy humans aren't going in to fight, they are going in to be squished, to symbolize human weakness against the machines. After a decepticon slams its fists into some concrete pipe sections, somehow creating a fiery explosion, gunships capable of engaging the enemy with missiles and canons from considerable distance approach low and close enough to be clobbered with a mere wave of mechanical arms. As an alleged depiction of a military engagement, it's beyond ludicrous, laughable on its face. Suspension of disbelief isn't possible: this isn't a battle; it isn't even a simulation of a battle. It's a simulation of battle simulation, an arrangement of symbols of battles. Here are our valiant heroes going into battle; here's our shockingly powerful foe, see how he easily puts our heroes on the back foot; but wait (!) here come our heroes again with reinforcements, to win the day with a bunch of soundbites: ["damn, I'm good!"], ["punk-ass decepticon"], ["any last words?"], "the fallen shall rise again", ["that doesn't sound good"], ["not today!", reload-click, bullet to the head]. That's just the first 8 minutes or so; it goes on for hours (!), with no variation in pacing that you wouldn't also expect in a 30-second movie trailer. Some other commentary roughly concurs with mine, though I didn't enjoy the spectacle or visual feast aspects, primarily because those spectacles are filmed too close to the action, and the subjects, transformed machines, have so many bits and bobs hanging out of them it's hard to tell where one begins and another ends, much like how camouflage breaks up outlines. Trying to figure out what's actually going on within the pace of the editing cuts would give me a headache. Besides, marvelling at the sheer density of signifiers and its generally jaw-dropping empty awfulness is more fun, in a perverse way.
Read More

Virtual method interception

Delphi XE has a new type in Rtti.pas called TVirtualMethodInterceptor. It was originally designed for use in DataSnap authentication scenarios (though I don't think it's currently being used there), but of course, making it only work for that would have been quite a limitation. What does it do? Essentially, it creates a derived metaclass dynamically at runtime that overrides every virtual method in the ancestor, by creating a new virtual method table and populating it with stubs that intercepts calls and arguments. When the metaclass reference for any instance of the "ancestor" is replaced with this new metaclass, the user can then intercept virtual function calls, change arguments on the fly, change the return value, intercept and suppress exceptions or raise new exceptions, or entirely replace calling the underlying method. In concept, it's somewhat similar to dynamic proxies from .NET and Java. It's like being able to derive from a class at runtime, override methods (but not add new instance fields), and then change the runtime type of an instance to this new derived class. Why would you want to do this? Two obvious purposes spring to mind: testing and remoting. Mock objects have been in vogue in the testing space in other languages for some time. By intercepting method calls, one may more easily verify that a particular subsystem is calling all the right methods, with the correct arguments, in the expected order; similarly, the subsystem can proceed with the return values from these method calls, without necessarily having to hit the database, the network, etc. for what should be a unit test. Remoting on the basis of method calls is somewhat less useful, especially when an unreliable and latency-prone network gets into the stack, but that's not the only usage point. The virtual method interceptor logic was originally implemented to be used as part of DataSnap authentication, so that a call that comes in from the network can still be checked as its code flow spreads throughout the graph of objects. Anyhow, here's a simple example to get started: uses SysUtils, Rtti; {$apptype console} type TFoo = class // Frob doubles x and returns the new x + 10 function Frob(var x: Integer): Integer; virtual; end; function TFoo.Frob(var x: Integer): Integer; begin x := x * 2; Result := x + 10; end; procedure WorkWithFoo(Foo: TFoo); var a, b: Integer; begin a := 10; Writeln(' before: a = ', a); try b := Foo.Frob(a); Writeln(' Result = ', b); Writeln(' after: a = ', a); except on e: Exception do Writeln(' Exception: ', e.ClassName); end; end; procedure P; var foo: TFoo; vmi: TVirtualMethodInterceptor; begin vmi := nil; foo := TFoo.Create; try Writeln('Before hackery:'); WorkWithFoo(foo); vmi := TVirtualMethodInterceptor.Create(foo.ClassType); vmi.OnBefore := procedure(Instance: TObject; Method: TRttiMethod; const Args: TArray<TValue>; out DoInvoke: Boolean; out Result: TValue) var i: Integer; begin Write('[before] Calling ', Method.Name, ' with args: '); for i := 0 to Length(Args) - 1 do Write(Args[i].ToString, ' '); Writeln; end; // Change foo's metaclass pointer to our new dynamically derived // and intercepted descendant vmi.Proxify(foo); Writeln('After interception:'); WorkWithFoo(foo); finally foo.Free; vmi.Free; end; end; begin P; end. Here's what it outputs: Before hackery: before: a = 10 Result = 30 after: a = 20 After interception: before: a = 10 [before] Calling Frob with args: 10 Result = 30 after: a = 20 [before] Calling BeforeDestruction with args: [before] Calling FreeInstance with args: You'll notice that it intercepts all the virtual methods, including those called during destruction, not just the one I declared. (The destructor itself is not included.) We can get more ambitious with what it does. I can change the implementation entirely, and skip calling the underlying (i.e. inherited) method body: procedure P; var foo: TFoo; vmi: TVirtualMethodInterceptor; ctx: TRttiContext; m: TRttiMethod; begin vmi := nil; foo := TFoo.Create; try Writeln('Before hackery:'); WorkWithFoo(foo); vmi := TVirtualMethodInterceptor.Create(foo.ClassType); m := ctx.GetType(TFoo).GetMethod('Frob'); vmi.OnBefore := procedure(Instance: TObject; Method: TRttiMethod; const Args: TArray; out DoInvoke: Boolean; out Result: TValue) begin if Method = m then begin DoInvoke := False; Result := 42; Args[0] := -Args[0].AsInteger; end; end; Here, I inhibit the invocation and hard-code the result to 42, while negating the first argument. The proof is in the output: Before hackery: before: a = 10 Result = 30 after: a = 20 After interception: before: a = 10 Result = 42 after: a = -10 I could have inhibited the call by raising an exception instead: vmi.OnBefore := procedure(Instance: TObject; Method: TRttiMethod; const Args: TArray; out DoInvoke: Boolean; out Result: TValue) begin if Method = m then raise Exception.Create('Aborting'); end; And output: Before hackery: before: a = 10 Result = 30 after: a = 20 After interception: before: a = 10 Exception: Exception It's not limited to interception before the logically inherited call, but also interception after the call, again with the opportunity to fiddle with arguments and return value: m := ctx.GetType(TFoo).GetMethod('Frob'); vmi.OnAfter := procedure(Instance: TObject; Method: TRttiMethod; const Args: TArray; var Result: TValue) begin if Method = m then Result := Result.AsInteger + 1000000; end; And output: Before hackery: before: a = 10 Result = 30 after: a = 20 After interception: before: a = 10 Result = 1000030 after: a = 20 And if the inherited implementation raises an exception, that can even be squashed: function TFoo.Frob(var x: Integer): Integer; begin raise Exception.Create('Abort'); end; // ... m := ctx.GetType(TFoo).GetMethod('Frob'); vmi.OnException := procedure(Instance: TObject; Method: TRttiMethod; const Args: TArray; out RaiseException: Boolean; TheException: Exception; out Result: TValue) begin if Method = m then begin RaiseException := False; Args[0] := Args[0].AsInteger * 2; Result := Args[0].AsInteger + 10; end; end; Output: Before hackery: before: a = 10 Exception: Exception After interception: before: a = 10 Result = 30 after: a = 20 One thing the TVirtualMethodInterceptor class doesn't have, however, is a way to unhook (unproxify) the object. If the object is never unhooked, it's important that the object doesn't outlive the interceptor, because the interceptor needs to allocate executable memory in order to create the little stubs with which it redirects method calls to the events. Fortunately, it's pretty trivial to do: PPointer(foo)^ := vmi.OriginalClass; Another point: the class inheritance chain is changed by the hooking process. This can be shown easily: //... Writeln('After interception:'); WorkWithFoo(foo); Writeln('Inheritance chain while intercepted:'); cls := foo.ClassType; while cls nil do begin Writeln(Format(' %s (%p)', [cls.ClassName, Pointer(cls)])); cls := cls.ClassParent; end; PPointer(foo)^ := vmi.OriginalClass; Writeln('After unhooking:'); WorkWithFoo(foo); Writeln('Inheritance chain after unhooking:'); cls := foo.ClassType; while cls nil do begin Writeln(Format(' %s (%p)', [cls.ClassName, Pointer(cls)])); cls := cls.ClassParent; end; // ... And output: Before hackery: before: a = 10 Exception: Exception After interception: before: a = 10 Result = 30 after: a = 20 Inheritance chain while intercepted: TFoo (01F34DA8) TFoo (0048BD84) TObject (004014F0) After unhooking: before: a = 10 Exception: Exception Inheritance chain after unhooking: TFoo (0048BD84) TObject (004014F0) The feature is primarily an infrastructure piece for advanced libraries, but hopefully you can see that it's not too difficult to get into.
Read More

What Nokia must do to stay relevant in mobile

Nokia is losing market share fast, which is being discussed in many places. Nokia's CEO Anssi Vanjoki also expressed his view on this topic. The number of mistakes, that Nokia currently does, is huge, let's take a few: * Focus on OS technology instead of customer-centric parameters. As Anssi puts it: "The current phase of MeeGo development is looking awesome." * Believing that the window of
Read More

Apple iPhone 4 signal strength indicator highlights a common problem

It is old knowledge that if progress bars go faster at the end, the user is happy. In other words, if the progress bar is modified so that it doesn't show the perfect progress percentage, you get a better customer satisfaction. The same principle applies to other indicators, like battery indicators and mobile phone signal strength. Many phones don't seem to lose battery energy until the very
Read More