Ayende @ Rahien

Hi!
My name is Oren Eini
Founder of Hibernating Rhinos LTD and RavenDB.
You can reach me by email or phone:

ayende@ayende.com

+972 52-548-6969

, @ Q j

Posts: 6,665 | Comments: 48,508

filter by tags archive

Code of the week

time to read 1 min | 172 words

This piece of code make me so happy:

private static IDictionary<string, Func<Stream, ICommand>> commandFactories =
	new Dictionary<string, Func<Stream, ICommand>>
		{
			//storage
			{"add", s => new AddCommand(s)},
			{"append", s => new AppendCommand(s)},
			{"cas", s => new CasCommand(s)},
			{"delete", s => new DeleteCommand(s)},
			{"prepend", s => new PrependCommand(s)},
			{"replace", s => new ReplaceCommand(s)},
			{"set", s => new SetCommand(s)},

			// retrieval
			{"get", s => new GetCommand(s)},
			{"gets", s => new GetsCommand(s)},

			//modifications
			{"incr", s => new IncrCommand(s)},
			{"decr", s => new DecrCommand(s)},

			//misc
			{"flush_all", s => new FlushAllCommand(s)},
			{"quit", s => new QuitCommand(s)},
			{"version", s => new VersionCommand(s)},
		};

This is something that I do quite often, and it is good to have a way to do it easily.

Elegant Code

time to read 1 min | 165 words

I just finished writing this, and I find it very pleasing to look at:

public class EntitiesToRepositories
{
	public static void Register(
		IWindsorContainer windsorContainer,
		ISessionFactory sessionFactory,
		Type repository,
		params Assembly[] assemblies
		)
	{
		if(typeof(IRepository<>).IsAssignableFrom(repository))
			throw new ArgumentException("Repository must be a type inheriting from IRepository<T>, " + 
"and must be an open generic type. Sample: typeof(NHRepository<>).
"); foreach (IClassMetadata meta in sessionFactory.GetAllClassMetadata().Values) { Type mappedClass = meta.GetMappedClass(EntityMode.Poco); if (mappedClass == null) continue; foreach (Type interfaceType in mappedClass.GetInterfaces()) { if(IsDefinedInAssemblies(interfaceType, assemblies)==false) continue; windsorContainer.Register( Component.For(typeof(IRepository<>).MakeGenericType(interfaceType)) .ImplementedBy(repository.MakeGenericType(interfaceType)) .CustomDependencies(Property.ForKey("ConcreteType").Eq(mappedClass)) ); } } } private static bool IsDefinedInAssemblies(Type type, Assembly[] assemblies) { return Array.IndexOf(assemblies, type.Assembly) != -1; } }

Tricky Code

time to read 1 min | 121 words

Without running the code, what is the result of this masterpiece?

class Program
{
	static void Main(string[] args)
	{
		DoSomething("a","b");
	}

	public static void DoSomething<T>(IList<T> set)
	{
		Console.WriteLine(set.Count);
	}

	public static void DoSomething<T>(params T[] items)
	{
		List<T> set = new List<T>();
		foreach (T t in items)
		{
			if (t == null)
				continue;
			set.Add(t);
		}
		DoSomething(set);
	}
}

It surprised the hell out of me until I figured out what was going on, then I was very amused. This code works exactly as it should be, to produce a very different result than the expected one.

Going into a new code base

time to read 2 min | 260 words

I had a chance at DevTeach to just take an hour and start looking at a large code base. I made the claim several times in the past that no matter the quality of the developers and the quality of the code base, there is no way someone can just sit down on a code base and start working on that.

I tried to grok the code without help, and I failed. I could probably do that, but it would take several days. That was especially true since it was in Windows Forms, and that is not a field that I have done much at. Not knowing anything about the actual domain was a big issue as well.

After about 30 minutes of sitting down and going over the code with the developer, I got a whole new level of understanding about the application. How it works, how the structure is built. I look at a test and can work how this is used, etc.

I still have very little knowledge about that application works, but after 30 minutes, I am confident in my ability to both grok the code and work with it. In fact, after getting the introduction to the code base, I can say that this is probably one of the better code bases that I have seen.

One of the more interesting parts was that when I looked at each class, it was when I took a step back and looked at the interactions it gotten really interesting.

It was a pleasure to read the code.

Pushing the limits

time to read 1 min | 87 words

Okay, I just finished writing this piece of code, I am not quite sure how to treat this. It is either elegantly concise or horribly opaque.

image 

I suspect both.

Somehow, you can probably wee that I have a C++ background, and even though the CLR doesn't give me the entire thing, you can still push it fairly far.

Of course, it still makes my head feel like this sometimes:

image

Can you figure it out? Functional caching

time to read 1 min | 109 words

Okay, here is a challenge, without running the code, what do you think should be the result of this program, and why?

public class Program
{
	private static void Main(string[] args)
	{
		Fetch<int> method = Get;
		method = AddCaching(method);

		method();
		method();
		method();
	}

	public static int Get()
	{
		Console.WriteLine("Called");
		return 1;
	}

	public delegate T Fetch<T>();

	public static Fetch<T> AddCaching<T>(Fetch<T> fetch)
	{
		T cachedObject = default(T);
		bool isCached = false;
		return delegate
		{
			if (isCached == false)
			{
				cachedObject = fetch();
				isCached = true;
			}
			return cachedObject;
		};
	}
}

Did you know: Find out if an exception was thrown from a finally block!

time to read 1 min | 169 words

This is a big biggie for me, because it enables a much nicer syntax for a lot of stuff. But first, let us show this:

using(new ExceptionDetector())
{
	if(new Random().Next(1,10)%2 == 0)
          throw new Exception();
}

How can you tell, from the ExceptionDetector, if an exception was thrown or not? Well, conventional wisdom, and what I thought about until 15 minutes ago, says that you can't. I want to thank Daniel Fortunov, for teaching me this trick:

public class ExceptionDetector : IDisposable
{
    public void Dispose()
    {
        if (Marshal.GetExceptionCode()==0)
            Console.WriteLine("Completed Successfully!");
        else
            Console.WriteLine("Exception!");
    }
}
Amazing!

Understanding Bad Code

time to read 4 min | 609 words

Frans' contribution to the conversation about maintainable code deserve its own post, but I would like to mention this part in particular:

you will not [understand the code]. Not now, not ever. And not only you, but everyone out there who writes code, thus that includes me as well, will not be able to read code and understand it immediately.

You know what? That is not limited to bad code. I had hard time grokking good code bases, simply because of their size and complexity (NHibernate and Windsor comes to mind). Other code bases are as large, but they have easier approachability, probably because they are dealing with less complex domain an tend to have a wide coverage rather than deep (MonoRail comes to mind).

A while ago I was involved with an effort to migrate an ancient system to SQL Server 2005. The system compromised of over 100,000 lines of code, spread over some thousands of files scattered randomly in a case sensitive file system (you can guess why this is significant). The code base was about 85% SQL and 15% bash shell scripts. The database in question was a core system and contained slightly over 4,000 tables. One of the core tables was called tmp1_PlcyDma and was used to do business critical processing. That code base took data driven code generation to a level I have never seen before. I gave up trying to track down 7(!) levels of code->generating code->execute code->generating code->rinse->repeat

To say that the code base was bad is quite an understatement. To mention that the only place where I could run the code was by using a telnet console into a test environment that was not identical to production is only the start. I could mention no debugging, runtime of ~5 hours, test time of ~3 hours, etc. The code grew organically over a ten years period and you could track the developer progress from merely annoying to criminally insane (he invented his own group by construct, using triple nested cursors and syntax so obscure that even the DBA that worked with the system for the last 5 years had no idea what was going on).

Perhaps the thing that I remember most from this project that we had a bug that kept two people hunting after it for three weeks. The issue was a missing ';'. Oh, and the criteria for success in this project was successful migration, with bug-per-bug compatibility, and no one really knew what it did, including the authors(!).

But, you know what, after a month or so of looking at the code, it got to the point where I could look at something like pc_cl_mn.sql and know that it would contains the monthly policy calculation, and that this piece of code was doing joins manually via cursors again, that plcy_tr_tmp.sql was the "indexes priming" script, etc, etc.

The code was still a horror, but once you understood that the authors of this code had a... "special" way of looking at databases, you got to the point where you could get the point of the code in an hour instead of a day, and then move that to a saner approach.

So, what does this horrifying story has to do with Frans' point above?

The premise that you can read and understand code immediately is highly dependant on what you are familiar with. I know of no one that can just sit in front of an unfamiliar  code base and start producing value within the first ten minutes. But on a good code base, you should be able to be able to start producing value very quickly.

rails:ConditionalRender - still trying to get WebForms to work right

time to read 3 min | 466 words

Well, as it turns out, there are some things that you can do to make WebForms more palatable. Smart use of ITemplate and some additional magic can take you a fairly long way. I am still severely limited (splitting behavior between markup & code behind is extremely annoying) in what I can do, but it  is good to know that it is possible:

<rails:ConditionalRenderer runat="server" 
    Condition="<%# ((Policy)Container.DataItem).Expired %>"
    DataItem="<%# Container.DataItem %>" >
    <WhenTrue>
        Policy has expired!
    </WhenTrue>    
    <WhenFalse>
        Policy is valid until <%# Eval("ExpiryDate") %>
    </WhenFalse>
</rails:ConditionalRenderer>
 
I am using it inside a repeater to keep the presentation logic in a single place.
 
The code to make this happen is something like this (typed from memory, you need about 80 lines to get it right).
 
[ParseChildren(true)]
public class ConditionalRenderer : Control, INamingContainer
{
    public bool Condition { get { .. } set { .. } }

    [Templatecontainer(ConditionalRenderer)]
    public ITemplate WhenTrue { get { .. } set { .. } } 
    [Templatecontainer(ConditionalRenderer)]
    public ITemplate WhenFalse { get { .. } set { .. } }

    public object DataItem { get { .. } set { .. } }
    
    public override void EnsureChildControls()
    {
        if (Condition)
            WhenTrue.InstansiateIn(this);
        else
            WhenFalse.InstansiateIn(this);
    }
}

FUTURE POSTS

No future posts left, oh my!

RECENT SERIES

  1. RavenDB 4.1 features (11):
    04 Jul 2018 - This document is included in your subscription
  2. Codex KV (2):
    06 Jun 2018 - Properly generating the file
  3. I WILL have order (3):
    30 May 2018 - How Bleve sorts query results
  4. Inside RavenDB 4.0 (10):
    22 May 2018 - Book update
  5. RavenDB Security Report (5):
    06 Apr 2018 - Collision in Certificate Serial Numbers
View all series

Syndication

Main feed Feed Stats
Comments feed   Comments Feed Stats