Sunday, September 18, 2011

Ruby on Rails and Haml

I've never been a serious Web developer. Some PHP 6 or 7 years later, very little ASP.NET time to time - that's all. Some 2 or 3 weeks ago, just for fun, I started learning Ruby. It's turned to be a rather beautiful language, almost free of any punctuation noise. I wrote some scripts automating the most annoying routines at work and started thinking - "what's next?".
Yesterday, I started reading a book and I'm getting more and more impressed by Ruby on Rails. But the things got really exciting when I tried Haml. I've never seen such a succinct and clear template language! I feel I'm falling into love with it right now :) Just take a look:

Sunday, August 28, 2011

Is Ruby such a good choice?

Let's see the Fibonacci implementation is C#, Ruby and Python.

C#:


Ruby:

Python:


As for me, C#'s Enumerable.Range() is somewhat messy compared to Ruby's and Python's variants.
Ruby's optional parentheses around arguments seem just right, as well as 'return' keyword which now looks spare in C# and Python for me.
Ruby's 40.times expression looks a bit weird, however, we could use more 'normal' loop like
for i in 0..39.
Python's absence of 'end' or '}' is the best thing in the whole language. I'm not joking.
So, I can't judge at the moment whether Ruby or Python code is more expressive or readable.

What about performance, C# wins with 9 secs, followed by Ruby with 1 minute and the Python variant took as much as 2 minute to execute. I must say that I don't bother about performance since in real life applications such numeric calculations encounter very rare and should not be done in dynamic scripting languages like Ruby or Python.

Wednesday, August 10, 2011

Going to get rid of git

After a whole month of fighting with Git I'm almost ready to switch to Mercurial (and to move my team as well).

Branching in Git is extremely flexible and, as a result, it's very, very annoying and error prone. Another cons of Git is lack of quality GUI. TortoiseGit is a clone of TortoiseSVN and does not mirror the Git concepts at all - it's nothing but a windows shell extension. GitExtensions is so horrible internally (I fixed some bugs and added a couple of features into it recently) that I don't believe it's going to get stable...

In the other hand, Mercurial has a superior GUI - TortoiseHg. I can't realize how the same company is able to do such a awful thing as TortoiseGit and such a wonderful one as TortoiseHg.

Sunday, June 5, 2011

Implementing Decorator pattern with Windsor Container

The Decorator design pattern makes it possible to extend an abstraction's behavior without touching the implementing class at all. I didn't use to use it as often as I should in the past, but as I'm reading (for the second time, btw) the fresh edition of the excellent Dependency Injection in .NET book by Mark Seemann, I'm getting to really understand how useful it could be.
But the most amazing thing is that how elegantly Windsor Container wires up Decorators. Everything you have to do is register the Decorators in outside-in order and resolve the abstraction. For example, if we have Abstraction interface and two implementations - Impl1 and Impl2:


and we would like Impl1 be injected into Impl2 via its constructor, then all we have to do is register Impl2 as the implementation of Abstraction, then register Impl1 in the same way (no explicit names are required for both). As a result, when we resolve Abstraction from the container, we get instance of Impl2 with its _inner field initialized with an instance of Impl1. Excellent! What's more, the same trick works for collection dependencies (i.e. IEnumerable'1): a Decorator with such a constructor gets all below registered classes as a collection, which is perfectly fits into resolving composite decorators.


In the other hand, having such an automation, we can't compose Decorators in more than one way at the same time. Though, I've not met this restriction in the reality yet.

Sunday, May 8, 2011

Avoiding Nulls with "Tell, Don't Ask" Style

A very interesting thought about another wonderful side effect of "Tell, Don't Ask" principle (Nat Price wrote in his blog):

"On the other hand, if the object tells a collaborator to do something with the value, it can choose, when the value does not exist, to just not tell it's collaborator anything or to tell the collaborator to do something different. There's often no need to represent the "does not exist" case as a data structure because it never gets passed around."

Sunday, May 1, 2011

Why .NET Events Suck

The .NET events are so common that almost nobody even thinks to consider practical alternatives to them. And that's a mistake. I'm going to show how much interfaces are better in OO sense.

Consider two simple implementations of a very common Listener scenario where one class is "listening" another for some useful events.

First, .NET event-based version:


And interface-based version:


The pros of the interface-based version are:

  • An instance of Worker always references to a not-null WorkListener, which is great point since the Listener is its Dependency.
  • ...and Worker claims about that as clear as possible - via its constructor. It's not possible to create a Worker without a valid instance of a class implementing WorkListener.
  • It's absolutely clear at a glance that AnotherClass plays WorkListener role. In the even-based version all we have is just a public method with a rather weird (in context of the rest class's public interface) name and semantic (Work's Done? What work? Who is call it? When?).
  • AnotherClass.WorkDone() is private which is a good thing - AnotherClass's public interface is not polluted with a method that's not a class's responsibility.
The only con I can see:
  • It's not multicasting. However, it's rarely the case when multicasting is really needed.

    Sunday, March 13, 2011

    About testing method parameters against null

    "Unless I’m publishing an API for general use, I don’t worry about testing method parameters against null. It’s too much code and too many duplicate tests. Besides, I would be testing the wrong thing.
    When a method receives null as a parameter, the invoker—and not the receiver—is missing a test." - J. B. Rainsberger