Wed, 26 Nov 2008
I made this for Thanksgiving this year, and have already been asked for the recipe, even though I haven't had any yet. So here goes.
- Brownie Layer
- 1 cup sugar
- 1 cup butter
- 4 Tablespoons water
- 2 cups semi-sweet chocolate morsels (~300g)
- 1/2 cup amaretto
- 2 teaspoons vanilla extract
- 4 eggs
- 1 1/2 cups all-purpose flour (~190g)
- 1/2 teaspoon baking soda
- 1/2 teaspoon salt
- 1 cup chopped or sliced almonds (optionally toasted)
- 1/2 cup chopped maraschino cherries
- Truffle Layer
- 8 oz cream cheese, softened
- 1/4 cup powdered sugar (30g)
- 1 cup semi-sweet chocolate morsels (~150g)
- 2-3 Tablespoons amaretto
- Topping
- 1 cup semi-sweet chocolate morsels (~150g)
- 1/2 cup whipping cream
- 1 cup sliced almonds, lightly toasted
- maraschino cherries for garnish
Brownie Layer
Preheat oven to 325°F. Prepare a 9×13 baking dish. (I line it with a sling of parchment paper and then spray it with Baker's Joy.)
In a saucepan, bring the sugar, butter, and water to a boil. Remove from heat. Add chocolate, amaretto, and vanilla extract, stirring until chocolate is melted. Add eggs, one at a time, stirring until blended.
Whisk together flour, baking soda, and salt. Add to chocolate mixture, stirring well. Stir in almonds and cherries.
Pour mixture into baking dish and bake for 42-48 minutes.
Leave them in the dish to cool.
Truffle Layer
While the brownies are cooling, beat the cream cheese and powdered sugar in a stand mixer on medium speed until the mixture is smooth. Melt chocolate and add with the amaretto to the cream cheese, mixing until well-blended.
Spread over brownies and refrigerate until firm, at least 1 hour.
Topping
In a saucepan, melt the chocolate in the whipping cream. Spread evenly over the brownies. Sprinkle with almonds and cherries. Refrigerate until set, at least 1 hour.
Cut into bars and serve.
Wed, 19 Nov 2008
I have simple needs. I have a base class with some generic behavior and subclasses with specific information for that generic behavior. More concretely, the subclasses need to provide the generic behavior with an ordered list of things that designate key fields on database tables. The best representation of those "things" in Delphi seems to be members of an enumeration:
type
TKeyField = (kfFoo, kfBar, kfBaz, kfQuux);
Since I need the list of fields to be ordered, I need them in an array:
type
TKeyFieldArray = array of TKeyField;
The declaration of the base class is pretty simple:
type
TBaseClass = class
protected
function GetKeyFieldList : TKeyFieldArray; virtual; abstract;
public
procedure DoSomethingWithKeyFields;
end;
As is the declaration of the subclass:
type
TSubClass = class(TBaseClass)
protected
function GetKeyFieldList : TKeyFieldArray; override;
end;
So where's the problem? Where's the hate? The hate is in the implementation. If Delphi had array literals, this would be easy. Something like:
function TSubClass.GetKeyFieldList : TKeyFieldArray;
begin
Result := [kfBar, kfFoo, kfQuux];
end;
But it doesn't. It has some special magic for array literals if they're the parameter to a function, but not anywhere else. It does, however, have a syntax for array constants. Perhaps this will work:
function TSubClass.GetKeyFieldList : TKeyFieldArray;
const
keyFieldList : TKeyFieldArray = (kfBar, kfFoo, kfQuux);
begin
Result := keyFieldList;
end;
But no. That TKeyFieldArray
is a dynamic array; Delphi doesn't
allocate any space for it, so it can't be a constant value. You have to
tell Delphi how big each constant array is, even though you're already
telling it how many elements are in the array. So perhaps this is the
solution:
function TSubClass.GetKeyFieldList : TKeyFieldArray;
const
keyFieldList : array[0..2] of TKeyField = (kfBar, kfFoo, kfQuux);
begin
Result := keyFieldList;
end;
But no. Because of Delphi's approach to static typing, those are actually different types, and are therefore not assignment-compatible. (See previous hates on this subject.) No, here is the code that Delphi makes me type for what should be a one-line function implementation:
function TSubClass.GetKeyFieldList : TKeyFieldArray;
begin
SetLength(Result, 3);
Result[0] := kfBar;
Result[1] := kfFoo;
Result[2] := kfQuux;
end;
And just earlier this morning I was pleased because I read that Delphi
2007 (to which I'll soon be upgrading from Delphi 5) has for...in
loops,
so I can finally have foreach
. (Can't get the generics and anonymous
functions in Delphi 2009, because we need .NET and that's not yet
available for Delphi 2009.) Oh, Delphi. The one hand giveth, and the
entire rest of the stupid, anemic, pox-ridden language taketh away.
Mon, 17 Nov 2008
I'm divesting myself of a lot of computer-related things that are taking up too much space in my apartment. Take a look at my stuff and let me know if there's anything you'd like to take off of my hands. Anything left after a couple of weeks will go to the electronics recycling center.