
Duck typing was coined in the Ruby community “as a semi-humorous attempt to say that, regardless of what class an object belongs to, its essential character — its type — is determined by the messages that it can respond to. As in, ‘if it walks like a duck, talks like a duck, and quacks like a duck — it’s a duck!‘”
For us working in static typed languages like C#, Java VB.NET or C++, a class is important because it tells you what an object can do. In dynamic languages like Ruby, the interesting fact is whether an object can handle a message, not which members it’s type has defined, or which interfaces that type implements.
But what if you’re stuck using a strongly typed language like C#? This was the itch that I tried to scratch with this project. The idea is simple. Dynamically create an adapter that implements the desired interface and forwards the calls to a wrapped object. If a method exists on the interface that doesn’t have the matching signature on the wrapped object, throw an exception.
What this does is that it let’s you move type safety from compile time to runtime. Which is how Ruby behaves.
This can be useful when you’re trying to be agile about your coding, or when you working with a interface that’s big. It let’s you focus on implementing the part of the interface you really need, instead of the whole interface at once.
How to use it:
If you have an object that has a Disposable() method, but doesn’t implement IDisposable, you write something like this:
[CSHARP]Disposable disposable = new Disposable();
IDisposable costume = Tailor.CreateCostume(disposable);[/CSHARP]
What you get is an object that implements IDisposable, but forwards the call to IDisposable.Dispose() to the objects Dispose method.
As an added feature, I also implemented the method_missing feature from Ruby. If you try to run a method on a Ruby object that’s not there, Ruby will first see if you’ve overloaded the method_missing method before throwing an exception. If you have, it will run that method. You could use this feature as a simple mocking system. Something like this:
[csharp]public class Mock {
public string CalledMethods = “”;
public object MissingMethod(
string methodName, params object[] parameters) {
CalledMethods += methodName + “;”;
return null;
}
}
[Test]
public void Test() {
Mock mock = new Mock();
IDisposable disposable = Tailor.Create(mock);
using (disposable) { }
Assert.AreEqual(“Dispose;”, mock.CalledMethods);
}[/csharp]
If you do find it useful, please let me know!
Why not just do what Visual Studio does by default, and create skeleton implementation of the interface; basically, just a bunch of function prototypes with:
throw new Exception(“This member has not been implemented yet.”);
as the only contents of each?
That seems a lot more “in theme” with C#, than trying to shove a square peg through a round hole.
Left by NIck on October 20th, 2006
Having “grown up” programming in the python community, I always assumed that we invented the term “duck typing”. However this was an interesting and informative search: http://groups.google.com/groups/search?q=%22duck+typing%22&start=370&sa=N&scoring=d& .
Looks like Rubyists coined the term, but Pythonistas jumped on the bandwagon pretty immediately.
Left by Bill Mill on October 21st, 2006
Nick, one of the reasons given for doing it this way was that you wanted to be very agile in your coding. If you are using an interface that is part of the code you are building, and that interface is not completely set, then this method will be a nice alternative to doing it the Visual Studio-way as you say. Otherwise you will need to change your tests (or test helpers or wherever the interface is used) when the interface later changes. If you are really only interested in this one method for a particular test, then I see this method as a nice way.
And if I know Andrés correctly, I am pretty sure he is not trying to tell us to do it this way all the time. This is just an example of how you can do things differently for different purposes.
Left by Chris Hedgate on October 22nd, 2006