Unix and OO

September 24, 2009

This is pretty interesting. The money quote:

All OO languages show some tendency to suck programmers into the trap of excessive layering. Object frameworks and object browsers are not a substitute for good design or documentation, but they often get treated as one. Too many layers destroy transparency: It becomes too difficult to see down through them and mentally model what the code is actually doing. The Rules of Simplicity, Clarity, and Transparency get violated wholesale, and the result is code full of obscure bugs and continuing maintenance problems.

I’m increasingly of the belief that the key to successful programming is to minimize the amount of code you write.

And more…

September 22, 2009

I think the worst thing about the MS tool chain is that it damages the brains of developers who use it. Look at my question here where I hope to find some guidance on how to manage generated code in Visual Studio. The responses are baffled why anyone should want to do this – why would you have a build system determine dependencies – just have the developer worry about it.

MS developers don’t even understand the concept of programs like make. Visual Studio is pre-1977 technology.

Another Microsoft Hate

September 22, 2009

An IDE should either own its project’s file structure (like Eclipse does), or it shouldn’t (for example, the usual VIM/make/svn unix way). Visual Studio’s half-assed, sometimes manage the project’s files, sometimes force you to go into Explorer and manage things yourself, is the worst possible choice.

To watch this in action, create a project in your solution called ‘A’. Then delete it. Then, try creating another project called ‘A’. You can’t do it. There’s no indication that this happened – you just have to know the undocumented internals of how Visual Studio works.

Now, I have to go into explorer and delete the ‘A’ directory. But now I’m worried – is that good enough? Are there other files that need to be deleted? Are there files I shouldn’t delete? Either let me control those files or leave them alone, please.

Today’s Microsoft hate

September 21, 2009

COM references. They force you to have the control you’re referencing installed on the system before you can build. This causes all kinds of chicken-and-egg problems (the old ATL #import statement had similar problems) – we’ve got a module that references other modules, but I can’t build module A until I build and *install* module B on the system.

The workaround is to use tlbimp.exe to create an interop DLL that wraps the COM object. But that’s not obvious, and novice .NET developers are most likely to just click over to the COM reference tab and add references that way. As usual, Microsoft makes doing the wrong thing easy and doing the right thing hard.

For reasons unknown, Microsoft decides to create a new directory for each test run when using the Visual Studio unit test framework.  It seems to do an ok job of finding all the binaries it needs, but even if you set “Copy to Output Directory” to “Copy Always” on your test data files, they won’t be copied to that directory and your tests will fail.

To get Microsoft to copy data files needed by your tests, add this attribute to your test function:

[DeploymentItem("my_data_file.txt")]

Total time wasted? At least two hours.

I started out writing “Today’s Microsoft hate”, but that seemed too optimistic.

After an hour of reading documentation general googling, I’m pretty confident that there is no way to use .NET’s XmlSerializer to directly create an XmlDocument. In other words, if you have a serializable object, and you want an XmlDocument, you need to:

  1. Serialize to a in-memory buffer
  2. Create an XmlDocument and then call it’s LoadXml on that buffer.

The actual code I’m using:

XmlSerializer serializer = new XmlSerializer(typeof(cardJob));
using (MemoryStream stream = new MemoryStream())
{
serializer.Serialize(stream, aCardJob);
stream.Flush();
stream.Seek(0, SeekOrigin.Begin);
cardJobXml.Load(stream);
}

Unbelievable.

Update:

Well, it turns out you can do this.  So, it only took two hours to figure this out…

XmlSerializer serializer = new XmlSerializer(typeof(cardJob));
using (XmlWriter writer = cardJobXml.CreateNavigator().AppendChild())
serializer.Serialize(writer, aCardJob);

I’ve been working on using Twisted to provide a simple web interface to an app I’m working on. Initially, I tried to use Twisted’s ‘tree of Resources’ to route URLs to resources, but Django’s regular expression matching style of url routing is much simpler and more powerful, and I really started to miss it.

Here’s my solution – a Resource that has a mapping from regex to a view function and overrides getChild to return a Resource that is just a simple wrapper around that view function. Works for me so far:

def make_path_string(prepath, postpath):
    return '/'.join(prepath + postpath)

class Resource404(resource.Resource):
    isLeaf = True

    def render_GET(self, request):
        request.setResponseCode(404, "couldn't find resource")
        request.write("404 - not found")
        request.finish()
        return server.NOT_DONE_YET
        
class LambdaResource(resource.Resource):
    """I am a dynamic resource, that is generated by a function, mimicing django's view functions"""
    isLeaf = True

    def __init__(self, appstate, template_env, fn, kwargs):
        self.appstate = appstate
        self.template_env = template_env
        self.fn = fn
        self.kwargs = kwargs

    def render_GET(self, request):
        # TODO support deferreds
        request.setHeader("Content-Type", "text/html; charset=utf-8")
        rsp = self.fn(self.appstate, self.template_env, request, **self.kwargs)
        return str(rsp.encode("utf8"))
        
    def render_POST(self, request):
        # TODO support deferreds
        request.setHeader("Content-Type", "text/html; charset=utf-8")
        rsp = self.fn(self.appstate, self.template_env, request, **self.kwargs)
        return str(rsp.encode("utf8"))

class RoutingResource(resource.Resource):
    """I replace the standard hierarchical url routing mechanism with a django-style, regular
    expression matching mechanism"""

    def __init__(self, appstate, template_env, urls):
        resource.Resource.__init__(self)
        self.appstate = appstate
        self.template_env = template_env
        self.urls = urls

    def getChild(self, path, request):
        requested_url = make_path_string(request.prepath, request.postpath)
        for url in urls:
            #log.msg("matching '%s' against '%s'" % (url[0], requested_url))
            match_results = re.match(url[0], requested_url)
            if match_results:
                log.msg("match with params:" + repr(match_results.groups()) + ", " \
                    + repr(match_results.groupdict()))
                return LambdaResource(self.appstate, self.template_env, url[1],
                    match_results.groupdict())

        return Resource404()