Archive for June, 2009

Using Interactive C# (REPL)

Thursday, June 18th, 2009

The REPL, that is Read Eval Print Loop, is a feature provided by many programming language environments today, such as Python, Ruby, Scala and Haskel. For those who are not familiar with the notion, you could think of REPL as an interactive interpreter (even though it’s not always implemented as one). You can find more info here.

It practically is an interactive prompt (like a UNIX shell, or Windows PowerShell), that accepts expressions in your favorite programming language syntax. There was no practical implementation of a REPL for C# until the Mono project implemented a C# Interactive Shell in Mono 2.2, called csharp. It comes with two flavors: 1). as a command line shell under the name csharp and 2). with a graphical front end called GSharp.

I am sure that every developer, novice or seasoned, needs to test out some small snippet of code, from time to time, to make sure that it does what it is supposed to do. This is also true for C# developers. However, in the absence of a REPL for C#, the only way to do that was by creating a whole new project in Visual Studio or MonoDevelop with a very simple console application. Not only it seems like an overkill if you just want to test a few lines of code, but you also end up with a bunch of little test projects that you are never going to need.

However, now that Mono implemented a C# REPL there is no need to create a test console project for everything. It is extremely useful if you want to test out some piece of code.

An example from my own experience is when, in a C# project I have been working on, I needed to dynamically create a list of enum field values and their string names. I was not 100% percent sure of the way I thought of implementing this, so I wanted to test it out first.

Here it is, in the csharp interactive C# shell, running from a Linux command line:

anirothan@netbook:~$ mono-2.4 csharp
Mono C# Shell, type "help;" for help

Enter statements below.
csharp> var fileModeNames = Enum.GetNames(typeof(System.IO.FileMode));
csharp> fileModeNames;
{ "CreateNew", "Create", "Open", "OpenOrCreate", "Truncate", "Append" }
csharp> var fileModeValues = Enum.GetValues(typeof(System.IO.FileMode));
csharp> fileModeValues;
{ CreateNew, Create, Open, OpenOrCreate, Truncate, Append }
csharp> var pairs = new Dictionary<string, System.IO.FileMode>();
csharp> for(int i=0; i<fileModeValues.Length; ++i)
 > pairs.Add(fileModeNames[i], fileModeValues.GetValue(i));
{interactive}(2,7): error CS1502: The best overloaded method match for `System.Collections.Generic.Dictionary<string,System.IO.FileMode>.Add(string, System.IO.FileMode)' has some invalid arguments
/opt/mono-2.4/lib/mono/2.0/mscorlib.dll (Location of the symbol related to previous error)
{interactive}(2,7): error CS1503: Argument `#2' cannot convert `object' expression to type `System.IO.FileMode'
csharp> var pairsCorrect = new Dictionary<string, object>();     
csharp> for(int i=0; i<fileModeValues.Length; ++i)               
 > pairsCorrect.Add(fileModeNames[i], fileModeValues.GetValue(i));
csharp> pairsCorrect;
{{ "CreateNew", CreateNew }, { "Create", Create }, { "Open", Open }, { "OpenOrCreate", OpenOrCreate }, { "Truncate", Truncate }, { "Append", Append }}
csharp> pairsCorrect["CreateNew"]
 > ;
CreateNew
csharp> quit;
null

That was fairly easy and simple. The intention was to create a dictionary of enum field names and values. For the sake of testing I used the System.IO.FileMode enum.

The flexibility of the csharp REPL does not end there. Here is an extract from a session in gsharp (The gtk+ graphical front-end to csharp) which actually creates a window with a dropdown list.

csharp> LoadPackage("gtk-sharp-2.0");
csharp> using Gtk;
csharp> var window = new Window("Simple dropdown list binding test with csharp REPL");
csharp> var vbox = new VBox();
csharp> var label = new Label("This is a simple test.");
csharp> vbox.PackStart(label);
csharp> var model = new ListStore(typeof(System.IO.FileMode), typeof(string));
csharp> var fileModeNames = Enum.GetNames(typeof(System.IO.FileMode));
csharp> fileModeNames;
{ "CreateNew", "Create", "Open", "OpenOrCreate", "Truncate", "Append" }
csharp> var fileModeValues = Enum.GetValues(typeof(System.IO.FileMode));
csharp> fileModeValues;
{ CreateNew, Create, Open, OpenOrCreate, Truncate, Append }
csharp> var model = new ListStore(typeof(System.IO.FileMode), typeof(string));
csharp> for(int i=0; i<fileModeValues.Length; ++i)
 > model.AppendValues(fileModeValues.GetValue(i), fileModeValues[i]);
{interactive}(2,48): error CS0021: Cannot apply indexing with [] to an expression of type `System.Array'
csharp> for(int i=0; i<fileModeValues.Length; ++i)
model.AppendValues(fileModeValues.GetValue(i), fileModeNames[i]);
csharp> var dropDown = new ComboBox();
csharp> var renderer = new CellRendererText();
csharp> dropDown.PackStart(renderer, true);
csharp> dropDown.AddAttribute(renderer, "text", 1);
csharp> dropDown.Model = model;
{ { CreateNew, "CreateNew" }, { Create, "Create" }, { Open, "Open" }, { OpenOrCreate, "OpenOrCreate" }, { Truncate, "Truncate" }, { Append, "Append" } }
csharp> vbox.PackEnd(dropDown);
csharp> window.Add(vbox);
csharp> window.ShowAll();
csharp>
The GSharp C# Interactive Shell in action.

The GSharp C# Interactive Shell in action.

There are some limitations though. For example, you cannot create classes (but you can put .cs files in the ~/.config/csharp directory that will be loaded automatically to the interactive shell) and there is an apparent lack of code completion features. However, these limitations are already being worked on and I hope they will become available with mono 2.6.

Creative ZEN X-Fi on Ubuntu 9.04 Jaunty Jackpole

Friday, June 5th, 2009

I have a Creative Zen X-Fi portable media player for some time now. I have managed to make it work with previous Ubuntu versions, but only after a lot of hard work of googling and meddling with the sytem.

I didn’t have the oportunity to test it with the latest Ubuntu since I upgraded everything to 9.04 up until a few days ago.

As with previous Ubuntu versions, 8.10 and 8.04, the Zen was not automatically recognized by any media player, or by Gnomad, which by the way is sooooo awful.

After doing some digging around in the ubuntuforums I found a way to make it happen.

The problem is that the version of libmpt (the library that makes things work) provided by the canonical repositories is an older one and does not support the player out of the box.

Running mtp-detect from the command line, connected to the player but seemed not to recognize it.

In the forums there was a reference for a PPA repository that contained more recent versions. I tried adding the repository to apt but could not get the libmtp package to upgrade (don’t know why). So, I simply downloaded the deb packages manually, libmtp8_0.3.5-0ubuntu1_i386.deb, mtp-tools_0.3.5-0ubuntu1_i386.deb, from here. Then I installed them manually with GDebi.

That did it. Running mtp-detect now, connected and recognized the player. So did Amarok, Banshee and Rhythmbox.

So, if you want to get your Createive ZEN X-Fi working under Jaunty then you simply have to manually install the 2 packages I mentioned above.