Cook Computing

 

« July 2002 »

NUnit 2.0 Beta 2

Sunday 28 July

I got an email from the NUnit team the other day announcing the latest version:

Some of the highlights of the new release include the following:

  • Attribute based mechanism for specifying test and test fixtures.
  • New Forms Interface that displays Tests and TestSuites in an Explorer like fashion. The interface allows you to run individual tests and/or suites from the forms interface.
  • Automatic construction of suites based on namespaces. Just provide an assembly and the test runner constructs a suite of all TestFixtures in the assembly.
  • Minimal amount of effort to upgrade due to inclusion of a backwards compatibility class called TestCase and the framework also looks for methods that begin with "test" regardless of case as it did in the past.
  • XML output from the console program.

I did some work with it today and found the new GUI tool very useful. Its still a bit flaky but even so I did some very effective testing with it. Highly recommended.

Posted by at 06:43 PM. Permalink.

Covariance in .NET

Friday 26 July

Going back to the topic of covariance discussed here a while ago, I came across the following on the DOTNET-CLR list in a thread called more wishes (Brian Harry is a .NET program manager type at MS):

- return type covariance & argument type contravariance support in the CLR (when a MethodImpl is used to override a method with a different return type or argument types)

[Brian Harry] We have talked about this a lot and I think we are going to be doing it in a not too distant future version but I'll have to check.

Its not as if my life would be incomplete without covariance in .NET but it would be nice to have it all the same.

Posted by at 04:25 PM. Permalink.

mod_asp.net

Thursday 25 July

Browsing through my list of RSS feeds this morning I expected to see something about the ASP.NET on Apache announcement due yesterday. I couldn't see anything but on the Covalent site I found this white paper. Its not obvious if any of this is open source but I suppose if it isn't then it will only be a matter of time before an OS equivalent is produced (unless MS have dastardly plans to prevent it with patents or whatever).

Posted by at 07:54 AM. Permalink.

Full Eiffel on the .NET Framework

Thursday 25 July

Raphael Simon and Emmanuel Stapf, the Eiffel developers, have an article on MSDN. Its an updated version of an earlier article and describes the current state of Eiffel for .NET - which they claim supports the full language.

The article describes support for MI using interfaces. It sounds a bit of a hack and it will be interesting to see how it works in practice.

I had a brief flirtation with Eiffel a few years ago. I learnt the language, wrote a fair amount of code, and even applied for one of the few Eiffel jobs in the UK. I was offered the job but it turned out the salary was considerably less than what I was already earning and there were subtantially higher commuting costs so unfortunately I couldn't take the job.

Maybe the best thing for Eiffel would be for Microsoft to buy Meyer's company, now called Eiffel Software Inc, or at least sell the .NET version of Eiffel. Its a great language and this might be compromised with MS involvement, but without big company support it may always remain in its niche. If Microsoft were selling the product IT managers would have confidence that it was going to be around for a long time. On the other hand maybe .NET integration is sufficient to bring the language into the mainstream. "Envision", the Visual Studio plug-in to be released soon, is going to cost $499 with an introductory offer at $299.

Posted by at 07:36 AM. Permalink.

Extract XML Element

Tuesday 23 July

I've been puzzling over an XML problem using .NET code. I want to extract an element from an XML document and create a new document with this element as the root element. The other part of the spec is that this must be done as efficiently as possible.

Take the following trivial example

<?xml version="1.0" encoding="utf-8" ?>
<multistatus xmlns="DAV:">
  <response>
    <href>http://www.foo.bar/container/>
    <propstat>
      <prop xmlns:R="http://www.foo.bar/boxschema/">
        <R:bigbox/>
      </prop>
      <status>HTTP/1.1 200 OK</status>
    </propstat>
  </response>
</multistatus>

I want to be able to extract each element under the prop element(s), e.g. the <R:bigbox/> element, and end up with documents like this:

<?xml version="1.0" encoding="utf-8" ?>
<R:bigbox xmlns:R="http://www.foo.bar/boxschema/"/>

The efficiency requirement led me to try an XmlReader approach: traverse to the first child element of each prop element and use ReadOuterXml to extract the node. Unfortunately this does not handle the namespace properly because ReadOuterXml returns:

<R:bigbox/>

If there was some way of determing the active namespaces at the current reader position (or simply pushing them onto a stack as the document is traversed) there would still be the problem of determining which namespaces are required for the XML elements being extracted. All feasible but a lot more work than I had expected.

So for the time being I ended up using an XmlDocument approach involving copying the node and inserting it into a new instance of XMLDocument. This does handle the namespace problem but is likely to be much slower when large documents are involved.

Posted by at 08:38 AM. Permalink.

.NET Show

Tuesday 23 July

I watched the latest episode of MSDN's .NET Show last night. I guess its aimed at people who haven't had much exposure to .NET yet because I didn't find anything new in it. They talked about downloadable clients but didn't go into any of the issues. One interesting snippet was that they claimed to have built Word as a managed app using the /clr C++ compiler switch.

Posted by at 07:40 AM. Permalink.

Viral Infection

Tuesday 23 July

The human sort. I've been suffering from a low grade viral infection the last few days. Not too ill to take off time from work but feeling tired all the time and unable to concentrate. As a software developer the lack of concentration is the worst part of it. I'm feeling slightly better today.

Posted by at 07:32 AM. Permalink.

void main()

Thursday 18 July

I was puzzled by Ingve's comment on my sample code in the entry on Koenig lookup. It turns out that according to the C++ standard main() must always return int. However most compilers also support void, contrary to the standard which only allows:

int main()

or

int main(int argc, char* argv[])

I used void main() to save a line of code in the sample. However I could have used int main() without a return statement because this is allowed by the standard: if execution falls off the end of main(), it is treated as though a "return 0;" was the last statement. Therefore the following program is valid C++:

#include <stdio.h>
int main()
{
  puts("Hello world");
}
Posted by at 10:30 AM. Permalink.

Practical Computer Language Recognition and Translation

Thursday 18 July

In case you missed the link on John Lam's site, Terence Parr's online (work-in-progress) book Practical Computer Language Recognition and Translation is well worth looking at. I read the chapter on Building Translators by Hand last night and found it an excellent example of clear and entertaining writing on what could be rather dry subject material.

Posted by at 08:41 AM. Permalink.

XML-RPC.NET FAQ

Thursday 18 July

I've uploaded a draft of the XML-RPC.NET FAQ. A few TBDs remain, and I have a few more questions I'd like to add, but the FAQ covers most of the key topics.

In the next release of the library the FAQ will replace the current documentation except for descriptions of samples. As I mentioned before this should reduce the amount of work required to keep the documentation up-to-date.

Posted by at 07:50 AM. Permalink.

Koenig Lookup

Tuesday 16 July

Following a link on the private virtual function thread I mentioned yesterday I ended up reading several articles on the C/C++ Users Journal site. One article mentioned Koenig lookup, another C++ feature I'd never encountered before.

The gist of Koenig lookup is that when resolving an unqualified function name (i.e. without a namespace prefix), the namespace of each argument is added to the list of namespaces in which the function name is searched for. For example:

namespace Tst
{
  class TstStruct { };
  void Foo(TstStruct ts) { } 
};

void main(void)
{
  Tst::TstStruct ts;
  Foo(ts);
}

Foo in main can be resolved because the compiler adds the namespace containing TstStruct to the list of namespaces to be searched.

If you only use VC++ then Koenig lookup is a moot point. I compiled this code with gcc on linux after I discovered that VC++ does not support Koenig. So I don't feel so bad about being completely ignorant of it.

This article explains Koenig lookup in more detail.

Posted by at 07:22 AM. Permalink.

Private Virtual Functions

Monday 15 July

When trawling through a backlog of over 1000 unread postings to the .NET list I was interested by the thread starting at this item. Quote: "i was just toying around, porting some c++ code to c#, and i discovered that private virtual member functions are not supported."

As later items state, private virtual functions are supported by the CLR. MC++ does support this feature but not C#, so one more to add to the list of features supported by MC++ but not C# (but its not the feature I was hinting about yesterday).

I tested this with the following code. This managed C++ code works as expected:

__gc class Parent
{
public:
  void Bar()
  {
  Foo();
  }
private:
  virtual void Foo() 
  {
    Console::WriteLine(S"Parent::Foo");
  }
};

__gc class Child : public Parent
{
private:
  void Foo() 
  {
    Console::WriteLine(S"Child::Foo");
  }
};

void _tmain(void)
{
  Parent* parent = new Child();
  parent->Bar();
}

but this C# code doesn't even compile:

class Parent
{
  public void Bar()
  {
    this->Foo();
  }

  <font color="red">private virtual void Foo()</font> 
  {
    Console.WriteLine("Parent::Foo");
  }
}

class Child : Parent
{
  <font color="red">private virtual void Foo()</font> 
  {
    Console.WriteLine("Child::Foo");
  }
}

The concept of private virtual functions was completely new to me and seemed strange at first, but they do make sense where functionality must be completely specific to a class (and so not callable from a derived class) even when a pointer to a base class is being used.

Posted by at 05:58 PM. Permalink.

XML-RPC.NET 0.5.4

Sunday 14 July

I have just updated XML-RPC.NET with version 0.5.4.

This release contains three changes:

(1) In some cases the name of a member in an XML-RPC struct might be invalid in the .NET programming language being used. To handle this the XmlRpcMember attribute is now available. This allows an XML-RPC member name to be mapped to and from a different .NET name. For example:

public struct SumAndDiffValue
{ 
  [XmlRpcMember("samples.sum")] 
  public int sum; 
  [XmlRpcMember("samples.difference")] 
  public int difference; 
}

(2) Classes derived from XmlRpcClientProtocol inherit a Headers property of type WebHeaderCollection. This can be used to specify custom headers which will be added to the HTTP request. For example:

SumAndDiffProxy proxy = new SumAndDiffProxy(); 
proxy.Headers.Add("TestHeader", "this_is_a_test");
SumAndDiffValue ret = proxy->SumAndDifference(2, 3);

(3) Deserialization of XML-RPC arrays has been changed so that if the parser determines that the elements of an array are all the same type, an array of that type is created. The motivation for this change was to improve usage of the system.methodSignature Introspection API method:

object[] signatures = proxy.SystemMethodSignature("samples.sumAndDifference"); 
foreach (string[] signature in signatures) 
  foreach (string param in signature)  	
  Console.WriteLine(param); 
Posted by at 05:29 PM. Permalink.

Online Again

Sunday 14 July

I returned from a vacation in Scotland yesterday. It was good to get away from everything for a couple of weeks though I have to admit I took a couple of books on Lisp with me (ANSI Common LISP and Common Lispcraft ). From a beginners perspective I would recommend both of them for providing a very thorough introduction to Lisp. All I need now is a serious Lisp project to work on.

I did manage to answer some XML-RPC.NET queries during the last few days and last night I implemented a couple of new features which will be in the release I plan to issue later today.

Other plans for this week are the release of two FAQs - one on XML-RPC.NET, the other on MC++ (I notice Tomas has announced his MC++ FAQ. Its tempting to have a look at this but I'll wait until I've released mine).

I've been working on the XML-RPC.NET FAQ for a while. I toyed with alternative ways of documenting the library but the most important factor turned out to be minimising the effort required. The FAQ format has allowed me to provide sufficient detail but without the hassle of formatting and maintaining a more complex document.

The MC++ FAQ should follow sometime soon. While working on this I discovered another CLR feature supported by MC++ and not by C# (see earlier entry here) but again its not going to cause a rush to MC++. You'll have to read the FAQ to find out what it is, unless Tomas' FAQ has already mentioned it.

Posted by at 03:41 PM. Permalink.