Twitter icon.
Random notes on software, programming and languages.
By Adrian Kuhn

Archive for December, 2009

Dependency Injection vs. Virtual Classes


Wednesday, December 30th, 2009

Every time you create an instance of a class by using the new keyword, you tightly couple your code to that class, and you will not be able to substitute that particularly implementation with a different one (at least not without recompiling the code).

Taken from an answer on stackoverflow that motivates dependency injection. Dependency injection however is not the real solution, it is rather a workaround for missing virtual classes. In this post I will show you why.

For example in

public class MyClass {
  public string sendMessage(String contents) {
    return new MailService().sendMessage(contents);
  }
}

you cannot use a different MessageService. This might not seem limiting at first sight, but think for example of testing. Your tests might be better off using a stub service that does not send actual emails.

This can and is being solved with dependency injection, yes. But the actual problem is rather a language problem: Classes are not virtual. While methods are virtual and thus looked up at runtime, classes are not.

In the following example, we can change the mail service by subclassing and overriding a method. This works because methods are virtual and thus late bound.

public class MyClass {
  public string sendMessage(String contents) {
    return newMailService().sendMessage(contents);
  }
  public MailService newMailService() {
    return new MailService();
  }
}

What a difference a single whitespace can make!

When newMailService is called, that method name is looked up in the context of the calling method. The context of the calling method is its class. Therefore, by subclassing the containing class we can provide a different mail service.

Imagine the same would happen with class names. Whenever we call new MailService() then the class name would be looked up in the containing context. Imagine further the lookup would not stop with the class but bubble up to the containing package. Then, by “subclassing” that package we might provide a different mail service.

Subclassing a package is nonsense terminology, let’s rather say that we instantiate a package … and let’s further assume that packages and classes are the same, and that our system is built of nested classes.

public class MyApplication {
  public class MyClass {
    public string sendMessage(String contents) {
      return new "MailService"().sendMessage(contents);
    }
  }
}

I have put the class name of MailService in quotes to remind you that it is the name of a virtual class name and thus looked up in the containing context.

Imagine further that we could pass the binding of classes to a class when creating it, then we could instantiate two versions of our application: one for real, and one for testing.

Application forTesting = new Application(MailService = TestMailer);
Application forReal = new Application(MailService = InterwebMailer);

Testing and production are not the only possible contexts. Imagine for example an XML parser. Typically it creates DOM nodes, but maybe you would prefer you own implementation of nodes. Maybe even the DAO objects of your application? There we go

XMLParser custom = new XMLParser(Node = Application.DAO);
XMLDocument doc = custom.new XMLDocument("example.xml");

NB, the second line is actually valid Java syntax: this is how you create an instance of an inner class when you are not in the same file as its outer class.

— So this is how dependency injection should really work!

And it is even not that far from reality. Both Beta and Newspeak (the new language by Gilad Bracha) do have virtual classes and both do have nested classes, and in both classes what I just described is how you decouple your packages in these languages.

And, hup hup hup, another design pattern has been disguised as a missing language feature :)

SUITE is Not Limited to Code Search


Tuesday, December 29th, 2009

The main focus of the SUITE workshop (co-located with ICSE) are search and software development. A frequently asked question is whether SUITE is limited to code search.

— SUITE is not limited to code search!

The general theme of SUITE is search-driven development. We consider search to be  a fundamental activity during software development. This includes (beside searching code, of course) search of external documents as well as search of runtime objects. Any search that may help when working with software.

Also, keep in mind that we are not only looking for solutions but also for studies of the problem space. So if you studied the search needs of developers, your results are as welcome as how to implement a new code search engine. The idea of SUITE is to explore all aspects of search in software development.

Lemme me give you an example that is not related to code only

  • Assieme by Raphael Hoffmann etal is a meta-search engine for software documentation. Search results are presented as a browsable combination of API documentation, code examples and other information found on the web. Interestingly enough, code examples are not taken from source code repositories but from HTML pages. So you get a selection of examples that were considered worth to be put on the web by someone out there. All examples are compilable and thus ready to be paste in your program.

For further inspiration, you may find an exhaustive list of topics on the SUITE website—of course, submissions to the workshop are by no means limited to the topics covered there. If you have any position on software search, submission is open until Jan 19, 2010.

We are looking forward to hear your take on software search.

Be a rebel!

Pharo Superpower: Use Anything as Class


Monday, December 28th, 2009

In Pharo Smalltalk, not only can you create anonymous classes at runtime, you can use anything as a class. You can create objects whose class is not a class. Mind boggling, ain’t it?

So if an object’s class is not a class, what is it then? Recall that in Smalltalk all classes are objects, thus if a class is not a class it is at least an object. When I first discovered this superpower I though “this must be a bug in the virtual machine”. However, the Blue Book of Smalltak-80 confirms that this is by design. The virtual machine of Smalltalk does not require that classes should inherit from Behavior.

In this post, I shall use an instance of Interval to create a new object whose class is … well, an instance of interval rather than a proper class.

The choice of interval is not a coincidence. In fact, we may only use objects as classes that have at least three instance variables. The first instance variable must refer to the superclass (which neither must be a class, but to keep things simple we’ll use Object in our example), the second instance variable must refer to a method dictionary, and the third instance variable must encode a magic number that specified the class format.

g := Interval basicNew.
g instVarAt: 1 put: Object.
g instVarAt: 2 put: MethodDictionary new.
g instVarAt: 3 put: Object format.

Next we compile a method that implements primitive #70 into interval. Primitive #70 can be used to create new instances. So we can use primitive #70 to create an instance of g.

Interval compile: 'primitive70 <primitive: 70>'.
gg := g primitive70.

Let’s verify that gg is really an instance of g. (Please refer to Phexample for more information on expectation matchers.)

gg class should beSameAs: g.
gg class should not beKindOf: Behavior.

Now we can add methods to the dictionary in g’s second instance variable and they become available on gg. We’ll add a method #zork that returns self.

methods := g instVarAt: 2.
methods at: #zork put: CompiledMethod toReturnSelf.
gg zork should = gg.

Unfortunately we cannot write gg should respondTo: #zork since g is not a real class and thus gg cannot send #canUnderstand: to g. Also you might not be able to print or inspect gg for the same reason, depending on the version of Pharo you are using.

Hackety hacking!

Pharo Superpower: Create Anonymous Class


Monday, December 21st, 2009

One of the superpowers in Pharo Smalltalk is to create new classes at runtime. Actually, whenever you accept a class definition in the class browser that very definition is evaluated to create a new class. And since all development in Smalltalk happens eo ipso at runtime the accpeted class definition creates a class at runtime. Superpower for the masses, it can be done.

In this post, I shall cover how to create anonymous classes at runtime. As an example, we’ll create an anonymous subclass of point that extends Point with a color attribute.

To create an anonymous class, you’ll first need to create an anonymous metaclass. (Hey, nobody said superpowers ain’t confusing!) The newly created metaclass needs a superclass, a method dictionary and a magic format number. Computation of format numbers is explained later.

m := Metaclass new.
m superclass: Point class.
m methodDict: MethodDictionary new.
m setFormat: 156.

Now we can create the actual anonymous class. Classes are instances of their metaclass. For each metaclass there is only one instance, thus if you send #new twice an error is thrown. As above, the newly created class needs a superclass, a method dictionary and a magic format number.

c := m new.
c superclass: Point.
c methodDict: MethodDictionary new.
c setFormat: 136.

Now we can create an instance of the anonymous class. We’ll verify the new instance to check that it actually meets our expectations. (Please refer to Phexample for more information on expectation matchers.)

p := c x: 3 y: 4.
p asString should = '3@4'.
p class should = c.
p class class should = m.
p should beKindOf: Point.

Next we’ll create accessors for the additional instance variable of c, which shall be named color. And we’ll also override #printOn: to report the color.

c setInstVarNames: { 'color' }.
c compile: 'color
    ^color'.
c compile: 'color: aString
    color := aString'.
c compile: 'printOn: out
    super printOn: out.
    out nextPutAll: '' is ''.
    out nextPutAll: color'.

Again, we’ll verify our instance.

p color should = nil.
p color: #yellow.
p color should = #yellow.
p asString should = '3@4 is yellow'.

I promised to explain how to compute the magic numbers above. The format number encodes both the number of instance variables and the type of an object. For example, an object can be indexable or not. All this is stuffed into a 32-bit number. To compute the format number, we’ll use a method in ClassBuilder that does the bit-fiddling for us.

metaformat := ClassBuilder new
    computeFormat: #normal instSize: 0
    forSuper: Point class ccIndex: 0.
format := ClassBuilder new
    computeFormat: #normal instSize: 1
    forSuper: Point ccIndex: 0.

Important for us are the parameters instSize: and forSuper: which expect the number of instance variables and the superclass of the to be created class. Please note, the number of instance variables should not include inherited instance variables, but only the number of to be added instance variables: which is zero for our metaclass, and one for our colored point class.

Hackety hacking!

For.example is Digg proof thanks to caching by WP Super Cache!