C# 3.0: Dictionary parameters (like in Ruby)

Eilon Lipton blogged about a way to get Ruby-like dictionary parameters in C# 3.0. (Link via Scott Guthrie‘s post on URL routing.)

Ruby lets you pass a dictionary as the last parameter(s) to a method. I won’t go into details, but the syntax looks like this:

get_html_link("Click me", "Key1" => "value1", "Key2" => "value2", "Key3" => "value3")

(Yes, the idiomatic usage would be to use :key1 instead of a string literal, but the strings are probably less confusing for the non-Ruby-adept.)

With Eilon’s code, you can get some very similar syntax in C#:

GetHtmlLink("Click me", new { Key1 = "value1", Key2 = "value2", Key3 = "value3" });

This code passes an anonymous type (that’s the new {...}), and then uses Reflection to read its properties. Reflection is not something you want to do in tight inner loops, but when readability is the main concern (as it is 95+% of the time), this technique is worth considering.

The place this is useful is when you’re really passing a dictionary of arbitrary values — when the function doesn’t know how many items to expect, or what they’ll be called. If, on the other hand, the function knows it’s expecting three properties called Key1, Key2, and Key3, you’d be better off defining a type with three properties, rather than using an anonymous type. Then the refactoring tools would be on your side, and you wouldn’t have reflection overhead. (The syntax wouldn’t change much, though — you’d just add the type name after new.)

Using anonymous types this way requires some work on the part of the function being called, to do the needed bits of Reflection. Eilon’s article includes sample code, although it leaves something to be desired; for example, he makes a new type for the key-value pairs, when KeyValuePair<> is already out there waiting to be used. And at that, why return a list of key-value pairs, when you could just return a dictionary?

Here’s my contribution. This version has the added advantage that you can pass in either a type with public properties (e.g. an anonymous type), or an IDictionary (generic or non-), and it does the Right Thing™. It returns a dictionary with case-insensitive key lookup, so you could use dictionary["key1"] just as well as dictionary["Key1"] (change it if that’s not what you want). Unit tests are left as an exercise for the reader.

public static IDictionary<string, TValue> ObjectToDictionary<TValue>(object o)
{
var result = new Dictionary<string, TValue>(StringComparer.InvariantCultureIgnoreCase);
if (o == null)
return result;
if (o is IDictionary)
{
foreach (DictionaryEntry entry in (IDictionary) o)
result.Add(entry.Key.ToString(), (TValue) entry.Value);
}
else
{
foreach (PropertyDescriptor prop in TypeDescriptor.GetProperties(o))
result.Add(prop.Name, (TValue) prop.GetValue(o));
}
return result;
}

The above code snippet is public domain; use it how you like.

Using the Microsoft Ergonomic Keyboard’s zoom wheel to scroll

Just ran across instructions on using the Microsoft Natural Ergonomic Keyboard 4000’s “zoom slider” as a scroll wheel instead.

The instructions involve compiling a JScript.NET application and running an XSL transform on the keyboard’s config file. But it looks to me like it’d be a whole lot easier to just open the config file in a text editor and make a couple of manual edits. I’ll have to try it when I get over this danged cold and get back to the office.

Parallel processing made easy

Microsoft Research and the CLR team are working on something called the Task Parallel Library, which looks like it will make .NET-based parallel processing a whole lot easier than it is today. The library is supposed to be released as a CTP sometime yet this year.

The article in MSDN Magazine has all the details, and is a great read. The parallel “for” loop looks extremely useful, and accordingly gets a lot of column inches in the article — including some tips on how much parallelism is too much, and things to think about when you tune its performance. They’ve also got a convenient way to execute two (or more) methods in parallel. The higher-level stuff is all implemented in terms of task and future classes that you can use on their own.

One of the best things about this library is that it handles exceptions nicely. If you run a loop in parallel, and any of the parallel threads throws an exception, all the other threads are canceled, and the exception is re-thrown in the place you originally started the loop — just like it would be if you’d used an ordinary “for” loop. This exception handling is baked into the base Task class, so it’s there for everything in the library.

I particularly liked some of the ways they squeeze the best performance out of the library. For example, if you create a future, and later you ask for its return value, but it hasn’t yet started to run, it’ll just be run immediately on the calling thread. No task switching. That’s kinda cool! They also optimize for single-core (e.g., Parallel.For just runs as a simple loop if you only have a single-core processor), and they scale up the number of worker threads if there’s a lot of blocking going on.

All in all, this looks like it’ll be a terrific library when it ships. Of course, I found this article after I’d put experimental multithreading support into DGrok! I’ll probably rip out my code and use theirs when they ship — they’re much more expert at multithreading than I am, so not only are they a lot more likely to get all the fringe cases right than I am, but they should be faster than mine as well.

Thanks to Allen Bauer for the link to the MSDN article.

Ready… set… NaNo!

All right, I couldn’t come up with a better title than that. Sorry. It’s early.

People have been asking me what my NaNoWriMo novel will be about this year, and my answer has been, “I have no idea.” But I got Chinese food for lunch yesterday, and my fortune cookie said, “Tomorrow your creative side will shine forth with exceptional ideas.”

If that ain’t a good omen, I don’t know what is. So… I’m off to write a novel. Wish me luck!

Non-trivial example of unmanaged exports

Chris Bensen just posted an example of passing non-trivial types — strings and interfaces — between Win32 and .NET using unmanaged exports. If you’ve ever wondered how to use unmanaged exports to pass anything more complicated than integers, this post is for you.

(And in case anyone was wondering, I’m the one who sent the question he’s responding to.)

Now I just need to find some spare time to tinker with this, because it’s prompting a number of questions in my mind. Can I put some attributes on the .NET interface to get rid of the IDispatch requirement? Do you have to use a var parameter to return an interface, or can you use an out parameter or a function? What happens when you throw an exception in .NET and catch it in Win32, and vice versa? How easy is it to pass callbacks (delegates) back and forth?

Of course, I don’t know if I’ll get that tinkering done very soon, for two reasons: (1) I’ll have to play with it on a work PC (my home PC only has Turbo Delphi for Win32), and (2) next month is NaNoWriMo.

DGrok 0.8: Faster and more configurable

DGrok 0.8 is now available.

You can now configure compiler options (IFDEFs, IFOPT, etc.) from the GUI. Your settings (compiler options, search paths) are saved from session to session. And the parser is probably around 20-25% faster (thanks to Brian for profiling and finding the hot spots).

Here’s the list of new GUI features:

  • FIX: .dproj-file exclusion got broken in 0.7. Made it work again.
  • CHG: Rules are now shown in a treeview instead of as hyperlinks. And the “Parse” button is back (along with its Alt+P accelerator).
  • ENH: Much-requested: Added “Compiler Options” page, where you can specify what to do with IFDEFs and IFOPTs.
  • ENH: Much-requested: Save settings (including search paths and compiler options) on exit, and reload on program startup.
  • ENH: Sped up parsing.
  • ENH: Show elapsed time after parsing.
  • ENH: When running an action, show a summary node with the action name and the number of hits.
  • ENH: Give a better error on duplicate filenames (it now shows these errors in the tree, instead of popping up an “unhandled exception” dialog).
  • ENH: Added Find (Ctrl+F) and Find Next (F3) to source-edit boxes.

New “find stuff” actions:

  • ENH: Added FindAsmBlocks action.
  • ENH: Added FindVariantRecords action.

Things you’ll see if you’re using the parser in your own code:

  • FIX: ToCode() was throwing exceptions on nodes with a trailing, empty ListNode (commonly seen with “procedure of object”). Fixed.
  • CHG: All node-type properties now end with the word Node.
  • ENH: Add a Projects collection to CodeBase.
  • ENH: Added ParentNode property to AstNode.
  • ENH: Added ChildNodes property to AstNode. When you need to iterate a node’s children, this is easier than using Properties. It also skips over nulls.
  • ENH: Added ParentNodeOfType<> method to AstNode.

DGrok 0.7 released: putting the parser to work

DGrok 0.7 is now available.

What’s new:

  • FIX: Initialized variables and typed constants now accept the empty list, ‘()’. The grammar doc already indicated this, but the code didn’t do it. It does now.
  • CHG: In package files, allow assembly attributes after the ‘requires’ and ‘contains’ clauses, rather than before. (I know they can come after, and that’s what I currently need to parse. If they can come other places, I’ll have to extend this later.)
  • ENH: Added support for undocumented {$SOPREFIX}, {$SOSUFFIX}, and {$SOVERSION} compiler directives.
  • ENH: The “search paths” box now allows a semicolon-delimited list of directories. As a side effect, there’s no longer a Browse button.
  • ENH: The “search paths” box now lets you put “\**” at the end of a search path. This means “include subdirectories”. Without that, it only does one specific directory. In a semicolon-delimited list, this gives you the ability to recurse into some directories and not others.
  • ENH: Added features to find all “with” statements, nested methods, and global variables in the code.

You’ll notice that there’s no longer a “Parse” button; instead it’s a hyperlink. This means that it no longer has a keyboard accelerator. Sorry — I miss it too. I’ll probably add a shortcut at some point.

There are five hyperlinks in this version:

  • Parse All: parses all the source files in the search path(s). You have to do this before any of the other links will enable.
  • Show Parse Results: resets the display to show the results of Parse All. This is only useful after you’ve clicked one of the later links, and want to get back to the thing that shows which files did and didn’t parse successfully.
  • FindGlobalVariables: Gives you a list of all global variables.
  • FindNestedMethods: Gives you a list of all nested methods (procedure inside a procedure, etc.).
  • FindWithStatements: Gives you a list of all the “with” statements.

Those last three are the bare beginnings of DxCop, a tool I’m eventually planning to write on top of the DGrok parser. DxCop (named after the .NET Framework’s FxCop) will analyze your code, looking for places where you aren’t following best practices. FxCop looks at your compiled code, while DxCop will look at the source, but it’s the same idea.

For those interested in looking at the code, all three “find” features will show you how to put the Visitor pattern to use. They’re only the beginning. Feel free to suggest other such features to add (or to send me code) — but keep in mind that DGrok doesn’t yet have symbol-table support, so anything involving “find references” isn’t possible just yet.

Mere-moments guide to creating custom ring tones for your Verizon RAZR V3m

I finally broke down and got a cell phone. Then I had a challenge: how to customize the ring tone.

See, I’ve always insisted that I won’t get a cell phone until I can set the default ring tone to Carmina Burana. I couldn’t lose face in front of my geek friends by admitting that I couldn’t figure out how to do it.

But apparently Verizon wants to make it hard for anyone to get ring tones without giving more money to Verizon, which I refuse to do on general principle. (And besides that, I kind of doubt that they sell “Carmina Burana” as a ringtone.)

It took me over nine hours, but I got it. (Stubborn little cuss, ain’t I?)

Now I’m sharing. Here’s how to make custom sound clips into ring tones for your Verizon RAZR, without voiding the warranty, in mere moments or less.

On not voiding the warranty

The RAZR supports custom ring tones. It’s Verizon that makes it hard. From what I can tell, they deliberately disable some of the phone’s functionality before they sell it, presumably so they can make more money selling their own ringtones.

There’s plenty of information out there about ways to re-enable the functionality, via SEEM edits and other forms of hacking the phone’s firmware. I didn’t do any of those, because they would have voided the warranty. Even though I’m not happy with Verizon for disabling features, I’m not going to re-enable them if I’m the one that’s going to get screwed. So I stuck to strictly non-hack methods.

What didn’t work

I bought the Media Essentials kit with my phone, so I tried hooking the phone up to my computer with the USB cable. Of course that didn’t work. You can use their software to transfer “songs” to the phone, but they differentiate between “songs” and “sounds”, and “songs” can’t be used as ringtones. And no, they don’t let you mount the phone as another drive on your computer so you can transfer “sounds” to the phone.

The phone can record “sounds” through its built-in microphone, and use them as ring tones. So I tried holding the phone up to the computer speakers. Result: volume nearly inaudible, quality far too crappy and under-watery. I didn’t expect this to work very well, but it was worse than I thought. So I’m not doing that.

I found some message board posts that suggested using the sound-recording capability to make a one- or two-second file, move it to the flash drive, take the flash drive out of the phone, plug it into a PC, and replace the files with identically-named files (including their weird extension) that are actually MP3s. This sounded promising, and it did get me sound files that play beautifully on the phone. But it still was a no-go. Why? Because apparently Verizon has caught on to this trick, and they’ve made it so that, as soon as you move a sound recording onto the flash drive, it’s forever unavailable to be a ring tone. Once you move it, it’s locked out. Even if you move it back to the phone’s internal memory, they won’t let you use it as a ring tone. Drat. (I spent $15 on an SD card reader, too. Isn’t it amazing how we Americans will spend money to avoid spending money?)

What did work

As of October 2007, here’s something that does work. (If you find in the future that it doesn’t work anymore, please leave a comment, so this page stays relevant.)

What you’ll need
  • A supported phone (see below)
  • Verizon service (these steps are very Verizon-specific)
  • Sound-editing software like GoldWave or Audacity
  • A sound file on your computer (if you need to rip a song from a CD, do that first)
  • One of the following:
    • A plan where you can get 250 (or whatever) incoming text/picture messages before paying extra, OR
    • A plan where you get unlimited incoming text/picture messages, OR
    • The willingness to pay Verizon 35 cents to get your custom ring tone onto your phone
  • Mere moments or less

I’m guessing that this should work on any phone that can receive sound attachments to picture messages. Here’s a list of phone models that have been confirmed as either supported or unsupported. If you have updates to this list, feel free to post a comment and let me know.

Supported Not Supported
Note: Aside from the RAZR V3m, these lists are based entirely on user feedback, and are not guaranteed to be correct. When in doubt, try it yourself.
The short short version

If you know what you’re doing, here’s the short short version: save the file as a 30-second-or-less, 22KHz WAV, and use Verizon vzwpix.com to send it to your phone.

The rest of this document takes you through this process, step by detailed step. So let’s get started.

Step 1: Create a Verizon vzwpix account

First, go to vzwpix.com. (You’ll get redirected to another Verizon URL, but in some places they still refer to it as vzwpix.)

Find the Login box on the left side of the page, and click the “Register” link. Then go through the steps to register. (This step can’t exactly be done in mere moments, but that’s Verizon’s fault, not mine.)

You’ll probably need to have JavaScript enabled to go through the registration process. Yes, this is stupid.

Once you’ve created an account, you’re ready to start moving a sound file to your phone. But first, you need to convert your sound file to have the proper length and format.

Step 2: Create the sound file

Your sound file cannot be in MP3 format. (Even if you rename the extension, Verizon will see that it contains MP3 content, and block the file. It’s not clear why they won’t accept MP3 content, since the phone can clearly play it.)

WAV format is what worked for me. It also has to be 30 seconds or less, and have a sample rate of 22.050 KHz or less.

I used the GoldWave trial edition to trim my sound file to less than 30 seconds, add a fade at the end, and save it as WAV. In GoldWave’s Save dialog, I set “Save as type” to “Wave (*.wav)”, and “Attributes” to “Microsoft ADPCM 22.050 KHz, 4 Bit, Mono”.

I’ve also heard a lot of good things about the Audacity audio editor, which is free. I’ve used GoldWave before; it has a lot of features but isn’t always quite intuitive. I’ve never used Audacity, so I don’t know what it’s like.

Mac users: see NL’s comments on Mac software for editing the sound file.

Step 3: Send the clip to your phone

Now that you’ve got a 22KHz WAV of 30 seconds or less, it’s time to get it onto your phone.

You’ll almost certainly need JavaScript enabled for this part.

Start by logging into your vzwpix.com account. Once you’re logged in, you’ll see the “Picture & Video Messaging” page.

Screenshot of the Picture & Video Messaging page you see after logging into vzwpix.com

In the bottom center of the page, you’ll see a red “Upload Media” button. Click it once. You may have to wait a long time for anything to happen, but if you click it more than once, the site gets confused, so don’t do that.

Eventually you’ll see this:

Screenshot of the Upload Media box you see after clicking the Upload Media button

Click the top Browse link. Browse to your WAV file and click OK. Then click the red “Upload” button, and wait a bit more.

After the “Upload Media” box closes, you’ll see your sound file in the “Uploads” box on the left. In this screenshot, I’ve uploaded two sound files. Notice that Verizon assigned them nonsense names, which I haven’t found a way to change (though I haven’t looked too hard).

Screenshot of the Picture & Video Messaging page after uploading sound files

Now, on the right side, notice the tall red box with stuff in it. A little over halfway down, there’s some white-on-red text that says “Drag audio here”.

Find your sound file on the left side, and drag it onto that “Drag audio here” text.

If you did it right, you’ll now see two tall red boxes. Ignore the second one.

Screenshot of the Picture & Video Messaging page after dragging the sound file to the right side

The first tall red box will now have a Play button (which for some reason is red, rather than the traditional green) in place of “Drag audio here”. You can use this to make sure you got the right audio file (since you can’t tell which one you’re dragging because of the nonsense names they assigned). If you got the wrong sound file, click the “X” (delete) button just above the tall red boxes, and try again.

You can just ignore the “1/1, 5 sec” stuff above the red boxes. I left that stuff alone and everything worked.

Okay, so you’ve got two tall red boxes, and the first one has the right sound file in it. You’re almost done. Click the red “Preview & Send” button in the lower right.

Screenshot of the Preview and Send screen

When the “Preview and Send” box opens, a 5-second clip of your sound file will play in your browser. Don’t panic! They didn’t lose the rest of the file. They have the whole file, it’s just that this screen only plays a 5-second clip.

In the “Send To” box, type your 10-digit cell phone number, without any punctuation. For example: 4025551212

Tip: If you just got your cell phone and don’t remember your phone number yet, here’s how to check it on a RAZR V3m. You can go to Menu > SETTINGS & TOOLS > System > Device Info > My Number. Or you can click the Voice button to the right of the display, wait for the menu to come up, and say “Check my phone number”.

Now type a subject line and click Send. The sound file will be sent to your phone, attached to a “picture message”.

Step 4: Save the clip as a ringtone

It will take a minute or two for the picture message to be sent to your phone. When your phone bleeps and tells you you’ve received a new picture message, select “View Now”, and your sound file will play on your cell phone, in all its glory.

You’re not done yet. Select “Options” (right soft button) and “Save Sound”. Give it a name and OK. It will pause for a moment, and then display “Sound saved”.

And… you’re done. Now you can select the sound as your master ring tone in the usual way, or assign it to individual contacts. Custom Verizon ringtones in mere moments or less.

Happy ringing!

Also in the Mere Moments series: Mere-Moments Guide to installing a Subversion server on Windows

DGrok 0.6.5 released: fixed $IFNDEF

DGrok 0.6.5 is available. It’s a minor bugfix release, hence the half-version.

What’s new:

  • FIX: {$IFNDEF UnrecognizedSymbol} was ignoring its contents. That’s the right thing for {$IFDEF} but not for {$IFNDEF}. Fixed.
  • ENH: Allow attributes in package files.
  • ENH: Add support for {$INLINE} and {$STACKCHECKS} undocumented compiler directives.

Ordinarily I would have gotten more done in an evening. It’s all Sam’s fault for distracting me with his Erlang talk last night.

DGrok 0.6 released: enter Visitor

DGrok 0.6 is now available for download.

New in this version:

  • All documented compiler directives are supported (plus one undocumented one, {$VARSTRINGCHECKS})
  • Added support for hard casts to the file keyword, e.g., file(AUntypedVarParameter)
  • Changed PointerType to allow any type, not just QualifiedIdent. This allows things like ^string.
  • Fixed runtime cast error when a program or unit has a beginend block or asm block for its initialization section. For simplicity’s sake, all init sections are now represented by InitSectionNode.
  • Ignore .dproj files when you search for *.dpr.
  • Ignore {$DEFINE} and {$UNDEF} when they occur inside a false {$IF...} block. Oops.
  • Ignore unrecognized compiler directives if they’re inside a false {$IF...} block. This lets me ignore, say, FreePascal compiler directives (since they usually occur inside {$IFDEF FPC} blocks).
  • Allow dotted names for packages (in the “Package Name” line).
  • Contains clauses now support “in filename” specifiers. (Actually, contains clauses are now handled by the same rule as uses clauses.)
  • Added support for [assembly: Attribute(...)] syntax. Yes, mostly I’ve been focusing on parsing Win32, but I have some need to deal with .NET code as well.
  • Changed it so that not-yet-defined symbols are treated as false by {$IFDEF} rather than explicitly raising an error. The error served its purpose earlier, but I reached the pain point and shut it off.
  • Added a Visitor class.

Whew. Not bad for one evening’s work.

I think Visitor will really be the way you put the parser to work. I was hoping to get some examples into today’s build, but I ran out of time. Play around if you like.