s1 = 0
(10...20).each { |x| s1 += x*x }
puts s1
s2 = 0
[3, 7, 9].each { |x| s2 += x*x }
puts s2
Really cool. First thing I loved straight away is the easy notation for ranges.
And then, of course, there's the each iterator which takes a block as parameter. Simply fantastic.
As a software developer who uses C# for most of his tasks at the moment, I was jealous. But then I thought: why just not do the same thing in C#?
Well, of course there is no fancy tripe-dot range notation is C#. But we can do it like this:
class Range
{
public static IEnumerable<int> FromTo(int from, int to)
{
int pos = from;
while (pos <= to)
{
yield return pos;
pos++;
}
}
}
Pretty easy to do with the help of the yield keyword.
OK, and what about each? You can implement that using a extension method:
static class IteratorExtensions
{
public static void Each<T>(this IEnumerable<T> enumerable, Action<T> action)
{
foreach (var item in enumerable)
{
action(item);
}
}
}
This defines a new method Each for IEnumerable<> types. It takes a parameter of type Action
Now let's take Range.FromTo and Each together and we rewrite the above Ruby script in C#:
int s1 = 0;
Range.FromTo(10,20).Each(
delegate(int x)
{
s1 += x*x;
});
Hmm, that is nowhere near the simple notation of the Ruby script...
But wait. Instead of using an anonymous method we also can used a lambda construct. Let's try it on the second part of the Ruby script:
int s2 = 0;
new[] { 3, 7, 9 }.Each(x => s2 += x*x);
Much better! Actually it almost looks like the Ruby script.
Conclusion: Ruby is nice, but C# isn't too bad either... ;-)