Ayende @ Rahien

Unnatural acts on source code

Boo trick: Even Nicer Hash Literals

Boo has the concept of Has Literals, and it can really make a difference in a lot of cases. It makes some things possible to write. Even leaving aside common things like dictionaries constants, consider this signature:

public void Configure(IDictionary options)
{
	// do work
}

In Boo, I can call this method like this:

config.Configure({
	"connection_string": 	"data source...",
	"batch_size":		15
//	etc
})

This  is much clearer than the C# option, but we can do better.

public class UnknownHashLiteralKeyToStringLiteral : ProcessMethodBodiesWithDuckTyping
{
	public override void OnReferenceExpression(ReferenceExpression node)
	{
		IEntity entity = NameResolutionService.Resolve(node.Name);
		//search for the left side of a key in a hash literal expression
		if (node.ParentNode is ExpressionPair 
                && ((ExpressionPair) node.ParentNode).First == node
                && node.ParentNode.ParentNode is HashLiteralExpression)
		{
                	ExpressionPair parent = (ExpressionPair) node.ParentNode;
	                StringLiteralExpression literal = CodeBuilder.CreateStringLiteral(node.Name);
	                parent.First = literal;
	                parent.Replace(node, literal);
	                return;
        	}
		base.OnReferenceExpression(node); 
	}
}

Now, we have to register it in the compiler:

compiler.Parameters.Pipeline.Replace(
    typeof(ProcessMethodBodiesWithDuckTyping), 
    new UnknownHashLiteralKeyToStringLiteral());

Now, we can write this kind of code:

config.Configure({
	connection_string: 	"data source...",
	batch_size:		15
//	etc
})

It make the syntax much clearer, and it make quite a bit of a difference in the clarify of the code. I am going to put it into Brail, MonoRail has quite a few of methods that takes dictionaries, and it would make the syntax even nicer.

Comments

Adam Tybor
06/11/2007 08:00 AM by
Adam Tybor

I thought we could do this already with Brail. This is how I pass configurations to ViewComponents, no?

Tobin Harris
06/11/2007 08:42 AM by
Tobin Harris

Nice trick! Reminds me or the Ruby style literals which I agree make for much more readable code...

class customer

has_one :account

mas_many :orders

end

I'd like to try Boo out, would you recommend it for use in commercial projects at this stage?

Ayende Rahien
06/11/2007 08:47 AM by
Ayende Rahien

Almost, you can do this:

component Grid, {@source: users}

I don't like the @ in the middle of it.

Ayende Rahien
06/11/2007 08:59 AM by
Ayende Rahien

Tobin, yes, that is what I was aiming for.

And yes, I would have little issue in using this for production. The IDE is #Develop, which isn't as polished as VS, but I find that the language more than make up for it.

Cedric Vivier
06/11/2007 09:24 AM by
Cedric Vivier

Niiice.

Have you opened a JIRA wish for inclusion of this handy trick in boo? :)

goodwill
06/11/2007 10:24 AM by
goodwill

Darn cool.... I wonder NVelocity can get something similar.... currently its:

"%{name='value'}"

I always come across missing literal errors :( could be my poor typing...

Ayende Rahien
06/11/2007 11:04 AM by
Ayende Rahien

@Cedric,

No, should I?

There is a chance of collision if you have:

foo = "bar"

hash = { foo: "fubar" }

What should the value be?

goodwill
07/20/2007 04:03 PM by
goodwill

You lurked me a lot on this :( too bad its not real yet.

For the question you ask, I think you might follow what ruby has done.

:foo =>:fubar, cleanest and distinguish between variable and string literal

(You dont even need =>, make it = is good enough)

Ayende Rahien
07/20/2007 04:10 PM by
Ayende Rahien

Goodwill,

The issue is with the language support, mainly.

Comments have been closed on this topic.