All 16 entries tagged Boo
No other Warwick Blogs use the tag Boo on entries | View entries tagged Boo at Technorati | View all 1 images tagged Boo
July 17, 2006
BooML Source Online
Follow-up to BooML SourceForge Project Pending from codeMonkey.Weblog();
The source for BooML is now online. The project is hosted by SourceForge. link
So far I've just got the source into SubVersion. I'm so busy at the moment (too many pies, not enough fingers!) – but I really must get some docs online too.
July 01, 2006
BooML SourceForge Project Pending
Follow-up to BooML – Language Integrated XML in Boo from codeMonkey.Weblog();
I have submitted a project request to SourceForge for BooML. I hope it is processed faster than Specter was!BooML – Language Integrated XML in Boo
Creating XML using the .NET XmlWriter object model tends to make your code look awful. I realised that using some mackery I could make Boo support creating XML right in the language. Thus was born "BooML"
Here is a little example.
import System
import System.IO
import System.Xml
import BooML
class Book:
[property(Title)]
private _title as string
[property(Author)]
private _author as string
def GetBooks():
return [
Book(Title: "Foo Bar", Author: "Bob Smith"),
Book(Title: "Test Title", Author: "Andrew Davey")
]
[XmlLiteral()]
def GetBooksXml(books):
books:
for book as Book in books:
book:
@id = book.GetHashCode()
title book.Title
author book.Author
xml = GetBooksXml(GetBooks())
print xml.ToString()
The resulting XML is:<?xml version="1.0" encoding="utf-8"?>
<books>
<book id="54267293">
<title>Foo Bar</title>
<author>Bob Smith</author>
</book>
<book id="18643596">
<title>Test Title</title>
<author>Andrew Davey</author>
</book>
</books>
The magic is in the XmlLiteral AST Attribute. It transforms macros (in the example: books, book, @id, title and author) into XML macros. The XML macros then in turn create the XmlTextWriter calls.
I think this could be a really powerful language enhancement for people doing web development who want to return abitrary XML from methods.
I may start a SourceForge project to open source the development.
June 27, 2006
Rhino Mocks Boo Macros Released
Writing about web page http://www.equin.co.uk/boo/rmbm.htm
My Boo syntactic macros for the Rhino Mocks mock object library are available to test. I've only spent a few days working on them but they are already powerful.
For download links and docs see preliminary documentation
June 23, 2006
Mackery: "Macro Hackery
I've been doing some pretty hairy stuff with Boo macros. AST manipulation to the extreme :p
I came up with the term "Mackery" – Macro Hackery!
June 12, 2006
BDD Meta–programming
I'm working on a Boo macro library for Rhino Mocks . I'm "dog-fooding" my Specter behaviour driven development framework in the process.I have to be able to specify how a macro should expand into real code. The spec code is now looking like this:
specify "x as int arg is sent as 0":
check(
ast { disallow foo.Bar(x as int) },
ast { foo.Bar(0); Rhino.Mocks.LastCall.Repeat.Never() }
)
I'm loving how flexible the Boo language is. It's hard to believe that the code is still Boo!
"check" is a function that expands the first argument using the macro being spec'd and makes sure it matches the second argument. (check is actual a partial application of a general check function that takes the macro first)
check = { input as MacroStatement, expected as Node | CheckMacro(macro, input, expected) }
def CheckMacro(macro as AbstractAstMacro, input as MacroStatement, expected as Node):
m = Method()
m.Body.Add(input)
NUnit.Framework.Assert.AreEqual(
expected.ToCodeString().Trim(),
macro.Expand(input).ToCodeString().Trim()
)
May 24, 2006
Light weight threading
I'm experimenting with light weight threads in Boo. I have an AST attribute that duplicates a method and inserts "yield" statements between each statement. This makes the method into an iterator that can be stepped through. I have a scheduler class that takes a list of methods and effectively runs them concurrently – but without all the heavy weight OS context switching.
Here is sample output from a demo program:
2 Processors
3000 Threads
Light weight threads:
Done in 45 milliseconds
.NET threads:
Done in 50236 milliseconds
About 1000 times faster!!
Note that I have two processors so the light weight scheduler actually creates two OS threads on which to run the light weight ones. This makes maximum use of my machine!
The code being run by the thread is in this class:
class Dog():
energy as int
def Eat():
energy++
def Bark():
energy--
[LightWeightThreadMethod]
def Live():
for i in range(100):
Eat()
Bark()
So basically I'm saying create 3000 dogs and run them all at once! Normal threads crawl due to the huge amount context switching. Light weight threads work like a dream :)
May 19, 2006
Specter Screencast
I have created a 15 minute screen cast demoing some of Specter's features. In the screen cast I create a simple specification of an object, using a behavior driven development style.
Play the demo (requires Macromedia Flash to be installed)
May 17, 2006
AssignFields Macro
Another handy Boo macro:class AssignFieldsMacro(AbstractAstMacro):
override def Expand(macro as MacroStatement):
ctor = (macro.ParentNode.ParentNode as Constructor)
b = Block()
for param in ctor.Parameters:
assign = BinaryExpression(
BinaryOperatorType.Assign,
ReferenceExpression("_" + param.Name),
ReferenceExpression(param.Name)
)
b.Add(ExpressionStatement(assign))
return b
This lets me do this:class Foo:
[property(Name)]
_name as string
[property(Age)]
_age as int
[property(Food)]
_food as bool
def constructor(name as string, age as int, food as bool):
AssignFields
# inserts:
# _name = name
# _age = age
# _food = food
f = Foo("hello", 42, true)
print f.Name
print f.Age
print f.Food
certainly saves a bit of typing!
May 16, 2006
RaiseEvent macro
— Update —
I Just found out Boo already does this!! When raising an event by:
Done(self, EventArgs.Empty)
the compiler knows it's an event (not a method) and puts in the null check, etc, on your behalf – so the macro I wrote is not needed. Ah well – was good practice I suppose :)
— End Update —
This is a handy macro I cooked up to generate the boring event raising code. Basically it looks like VB.NET's RaiseEvent keyword.
namespace Equin.Bootilities
import System
import Boo.Lang.Compiler
import Boo.Lang.Compiler.Ast
class RaiseEventMacro(AbstractAstMacro):
override def Expand(macro as MacroStatement):
assert macro.Arguments.Count >= 1
assert macro.Arguments[0] isa MethodInvocationExpression
method = macro.Arguments[0] as MethodInvocationExpression
# create event reference
evt = MemberReferenceExpression(SelfLiteralExpression(), method.Target.ToCodeString())
# prototype code for event invocation
code as IfStatement = ast:
if Thing is not null:
Thing.Invoke()
# change 'Thing' to actual event expression
be = code.Condition as BinaryExpression
be.Left = evt
mie = (code.TrueBlock.Statements[0] as ExpressionStatement).Expression as MethodInvocationExpression
(mie.Target as MemberReferenceExpression).Target = evt
# add arguments for the invoke
for re in method.Arguments:
mie.Arguments.Add(re)
return code
Sample usage:class Foo:
event Done as EventHandler
def Test():
RaiseEvent Done(self, EventArgs.Empty)
# This creates the following
#if Done is not null:
# Done.Invoke(self, EventArgs.Empty)
f = Foo()
f.Done += { print "done" }
f.Test()