Monthly Archives: February 2009

Ow ow ow

I’m back to trying the one hundred pushups exercise program – they even have a spiffy new logger now – and yesterday was week 1, day 1. I feel like someone beat me up with a baseball bat. It’s going to feel worse tomorrow, and tomorrow’s week 1, day 2. Ow. Ow ow ow.

I’ve got the prosthesis now, trying to get used to it. It looks great, but feels weird. More on that, possibly with pics, later when I feel less lazy.

Nope, this is not the way to impress me

[Update: I was contacted by SlickEdit support. They provided the patch for me, updated the forum post to contain the correct support address and were generally very friendly. Lesson learned: wait a day or two before posting ,-) I’m leaving this post up anyway, since it’s an accurate description of the events and my impressions yesterday.]

Today I was working on some Flex code, popped over to StackOverflow and saw an ad for SlickEdit. Curious, I cliked the ad to refresh my memory about the product, and I noticed they boast Vim-like input. That makes me instantly want to like an editor. Even better, they offer a plugin for Eclipse, SlickEdit Core. I’ve been less than pleased with ViPlugin, my current Eclipse-Vim provider, because it doesn’t want to play ball with Flex too well, and it has an irritating bug where a blank line at the end of a document causes the cursor to always revert to the top of the file, no matter what I do. (Note to self: the plugin has been updated.)

Anxious to try how SlickEdit works, I installed the plugin. It bugged me about getting a trial license key, which went relatively smoothly. The editor itself seemed fast, the Vim-emulation felt comfortable, but opening a MXML file still popped up the Flex editor, and I couldn’t figure out a way to change that. Instead of working through all the options, I searched Google for an answer, and found a forum posting saying they have a patch that improves Flex integration, and provides breakpoints and suchlike to the SlickEdit editor. Considering the debugger is a feature I end up needing (more often than I’d like), I was suddenly very interested. The posting said to email their support for the patch. So I did, and this is what I got:

We were unable to match your email with the subject “Flex Builder support for SlickEdit Core?” to an open case in our support system. If you were replying to an existing case, please include the case number (in the format of CAS-#####-####) in your subject line. If you wish to open a new case please submit your request using the in-product mechanism:

  • From within SlickEdit® 2008 via Help > Contact Product Support
  • For SlickEdit® Core for Eclipse™ you can do this via Help > SlickEdit Support Web Site and click on the "Open a Support Case" link
  • For SlickEdit® Tools for Microsoft® Visual Studio® you can do this via SlickEdit > Contact Product Support

Alternatively, if your product is not running you can submit your request on the SlickEdit Website at http://www.slickedit.com/supportcase/ Thank you,

SlickEdit Product Support

The tone is polite, but what the… can’t you guys accept regular email without making me jump through hoops? I was evaluating the product for work, and while at home I can spend time doing stuff like blogging about things that bug me, at work I really should be working. So if you make it hard for me to evaluate your product for my day-to-day needs, odds are I’m not going to.

Now, you could make a fair case by noting that I usually buy single licenses, rarely buy anything that exceeds 200€ in price and so on and so forth. But I really wanted to like the product, and I had already decided that $99 really wasn’t a bad price at all.

You could also say, well, this patch is for existing customers only. Fine, if that’s the case, then you’re not the company I want to do business with. If I can’t make your product work for me, that’s pretty much the end of the story right there.

I tend to advertise products I do like with considerable vigor – I’ve managed to sell a bunch of ReSharper licenses on JetBrains’s behalf. Too bad the JetBrains Seeder program was established after I had done so…

… anyway. Here’s the deal: I’m always looking for good tools at prices I can easily afford to pay myself. When I find them, I want a web site that displays the features in an easily navigable way, a payment processor that is secure and easy, a license system that either doesn’t exist at all or will provide the license for me straight after the payment has been verified, and a company that actually wants to do business with me. Take one or more of those away, and your product needs to be seriously amazing and/or mandatory for something I’m doing before I cough up the dough.

In the meantime, I’m still in the market for a good Vi/Vim plugin for Eclipse, preferably one that plays nice with existing editors.

[edit]

It occurs to me that SlickEdit support is probably in another time zone (duh), so perhaps I’ll be getting a reply during the night. If that’s the case, I’ll happily re-evaluate the situation. Even so, the email response I got gave me the feeling that I had done something wrong, and that they wouldn’t contact me unless I re-submitted my request through another means.

Changing the version of an assembly reference on the fly

Today I wrote a small wrapper for the Quartz.NET scheduler library to integrate it into a project I’m working on. The project has been using MySQL Connector/.NET version 5.1 for its database needs for a while now, and I was intent on storing the Quartz scheduler jobs in the same database, using the same library.

Quartz comes with a pre-configured set of ADO.NET providers. It allows you to set the connection string, user name and whatnot, but what it doesn’t allow you to do is override the class names it uses to instantiate the ADO.NET provider classes. That’s a bit strange, since near as I can tell, it contains a mechanism that could allow that.

That, in itself, wouldn’t be a problem. But we were using MySql.Data.dll version 5.1.3.0 and the embedded property file in Quartz.dll specified version 5.1.6.0.

API-wise I suspected that nothing remarkable had changed, and that we’d be able to use 5.1.3.0 – in fact, my colleague had successfully recompiled Quartz from source to use that version, and everything had worked. But I really didn’t want to include the Quartz sources in our build, we have more than enough projects already.

I had a recollection that there is a mechanism that allows to change the assembly on the fly, but I couldn’t recall what it is. So I began to type my question at StackOverflow, and lo and behold, one of the suggested already-asked questions had a comment that mentioned Assembly Binding Redirection. That rang a bell, I followed the link, and no more than two minutes later I had managed to force Quartz to use the version of MySql.Data I wanted it to use. It’s this simple:

<configuration>
   <runtime>
      <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
         <dependentAssembly>
            <assemblyIdentity name="myAssembly"
                              publicKeyToken="32ab4ba45e0a69a1"
                              culture="neutral" />
            <bindingRedirect oldVersion="1.0.0.0"
                             newVersion="2.0.0.0"/>
            <codeBase version="2.0.0.0"
                      href="http://www.litwareinc.com/myAssembly.dll"/>
         </dependentAssembly>
      </assemblyBinding>
   </runtime>
</configuration>

I suppose I should qualify this post with a “be sure you know what you’re doing if you use this.” You need to be sure that the substituted assembly obeys the contract of the original, otherwise you will likely break things.

This is a powerful mechanism to have, and since I had forgotten it once already, I thought I’d document it here to make sure it doesn’t happen again. .-)

C# using statement, redux

Last week, I wrote about the things I had not known about the C# using statement:

Multiple objects can be used in with a using statement, but they must be declared inside the using statement, like this:

using (Font font3 = new Font("Arial", 10.0f), 
           font4 = new Font("Arial", 10.0f))
{
    // Use font3 and font4.
}

I’m beginning to wonder where it was I learned the using statement from, given that I really didn’t know this is supported. Granted, I learned my C# basics when the language was version 1.0, and while the older reference does have an example of this usage, it’s not as clear as the current version. Still, lacking this knowledge meant that I’ve (ab)used braceless blocks to achieve the same effect:

using (Font font3 = new Font("Arial", 10.0f))
using (Font font4 = new Font("Arial", 10.0f))
{
    // Use font3 and font4.
}

I wasn’t actually as far off as I thought – what the documentation doesn’t clearly spell out is that the syntax for the variable declaration inside the using statement must match a normal variable declaration. And there’s no way to do this:

string foo = “bar”, int baz = 42;

Because C# only allows you to initialize variables of one type in one declaration, and the same limitation applies to the using statement. The compiler knows this, the documentation wasn’t so clear about it. I’ve rarely declared two variables of the same type like in my example – instead, it’s been more like this:

using (DbConnection connection = OpenConnection())
using (IDataReader reader = connection.ExecuteReader(“…”))
{
    // ...
}

in which case the neater syntax doesn’t actually work at all. So I’m still stuck with my syntax abuse, unless I want to nest blocks. And this sort of seems to communicate my intent: I’m trying to say, the usages of these two things are linked in scope. Were I to do something to the connection before running the statement, I’d of course indent them differently.

I’m still waiting for a better idea.

Holy crap, Delphi is alive and kicking

Holy crap, it looks like CodeGear is actively doing Good Things to keep Delphi alive! Apparently, Delphi 2009 supports anonymous functions:

Not only that, the language (Object Pascal) has finally woken from its stagnated state and is getting increasingly modern. It now implements, for instance, closures (anonymous methods) which is quite rare for a non garbage collected language.

Now, while the first paragraph should convey my excitement about the development, that alone isn’t quite enough to bring Delphi back to the front lines. I’ve used several versions of Delphi (5, 6, 7, 8 and 2006), and since version 6, seen quite a few problems with the tools and libraries. First of all, Delphi 7 deprecated a number of components without providing a migration path – only to introduce the very same components in source code, the demos folder of all places.

Delphi 8 was half-baked. The IDE was buggy, the forced migration to .NET was a bad idea, and the company quickly reversed their direction with Delphi 2005. A bug we discovered for Delphi 8 still existed two major versions later in the 2006 edition. When I finally figured out the steps to trigger it and reported it to Quality Central, I got no response. Eventually, the bug was closed with the response: “feature has been removed.”

Oh, and one of the crowning moments: I phoned Borland’s Finland offices to ask a licensing question, only to be told that they don’t handle those issues. At all.

After a history like this, CodeGear needs to pull some serious stunts to regain credibility. Evolving the language is not a bad start.

Reading up more on CodeGear’s latest, Delphi for .NET seems to be resurrected as Delphi Prism, powered by a compiler from another vendor, RemObjects software. What I find notable is that the RemObjects Oxygene compiler has boasted support for Mono since I first saw it. In fact, cross-platform applications running on OS X and Linux, courtesy of Mono are a feature highlight.

Now, if CodeGear can manage to nurture the community of Delphi developers in a way that matches the .NET and Java communities, things could be looking up.

Welcome back, Delphi!

Things I didn’t know (or remember) about the C# using statement

Declaring disposables outside the using statement

The first thing that surprised me was that you don’t have to declare the IDisposable in the using statement. Maybe because something like this:

public class Foo : IDisposable 
{
	Bar bar = new Bar();
	
	public void Dispose() 
	{
		using(bar)
		{
			bar.DoSomething();
		}
	}
}

doesn’t quite feel natural to me. However, MSDN does mention that this usage is possible, so I shouldn’t be surprised. I came across this one when trying to avoid writing a try/finally pair to dispose of a member variable inside a Dispose method.

Multiple IDisposables in a single using statement

While browsing the documentation for the using statement, I came across this gem:

Multiple objects can be used in with a using statement, but they must be declared inside the using statement, like this:

using (Font font3 = new Font("Arial", 10.0f), 
           font4 = new Font("Arial", 10.0f))
{
    // Use font3 and font4.
}

I’m beginning to wonder where it was I learned the using statement from, given that I really didn’t know this is supported. Granted, I learned my C# basics when the language was version 1.0, and while the older reference does have an example of this usage, it’s not as clear as the current version. Still, lacking this knowledge meant that I’ve (ab)used braceless blocks to achieve the same effect:

using (Font font3 = new Font("Arial", 10.0f))
using (Font font4 = new Font("Arial", 10.0f))
{
    // Use font3 and font4.
}

which not only is questionable in terms of syntax abuse, but also more verbose than the better way.

Variables declared inside a using statement are read-only

This one is courtesy of ReSharper’s background compilation. I was cleaning up code that opened a database connection twice by moving the opening statement to the outer scope and converting a try/finally pair to a using statement, when I got this message (I’m futzing with File.Open here purely for illustrative purposes):

ReSharper showing an error when trying to assign to to a variable declared inside a using statement

This makes a lot of sense, but is still somewhat surprising, given that C# does not have a way to declare read-only local variables. Another thing that seems a bit inconsistent to me is that when the declaration is outside the using statement, the compiler doesn’t mind if you assign to it:

When the declaration is moved outside the using statement, reassigning is possible again

which doesn’t make so much sense to me. I’m sure there’s a reason, but when I read that, I’m thinking whatever is assigned to foo before the using statement will be disposed of. I’m fairly sure that isn’t the case when reassigning is allowed.

So if I didn’t know this about the using statement, how well do I know C#?

I thought I knew the C# language pretty well, since it has been my primary tool at work for quite some time now. Turns out I was really, really wrong. I think I’m going to get a C# 3.0 language reference book just to go through the different aspects of the language and see if there are other places where I’ve missed something obvious.

The bigger question is, how can I ever hope to master even this one language, if details like this have eluded me for over four years, especially since C# is evolving rapidly.

Back in business

Back to work since yesterday, and hoo boy, it’s good to be alive. It didn’t take long for the hair pulling and swearing to begin, but in a good way. I enjoy the challenge of trying to clean up a messy code base – what I don’t enjoy are the days when progress is scarce.

Popped by the Uni for some Data Structures exercises and to catch a glimpse of my co-students. I felt like staying in, just because I really like the blend of people who appreciate quirky humor, geekiness, caffeine and code.

Today’s challenge was (and tomorrow’s still is…) creating a scheduled task that accesses some features that were – I hesitate to say “designed” – never thought to be useful outside a scenario where we know of a single logged user. It’s not feasible to try to extend the session concept to include a “working as the system here” type of session, due to a large number of potential, unexpected consequences. Hence the sane response seems to be to try and carefully write out the bits that always expect a session to be had.

Normal sleeping patterns are creeping in, after two nights of short, restless sleep and two consecutive mornings of still getting up between 6:15 and 6:45. Good thing I know this works, otherwise I might not have the willpower. I had almost three weeks to sleep as much as I wanted. That’s something I could get used to.