Fun coding tips – by Carsten Gehling

Please read this post for my reasons behind this article series.

There are few things more aggravating – at least as a programmer working with multiple languages – than when a certain construction is implemented in two extremely different ways. I tend to mix them up and often try using the idioms from one language in the other.

One of these is the yield keyword, which is a very strong construction in functional programming. It exists in both Ruby and C# but works quite differently.

Let’s take Ruby first. yield basically breaks execution, and calls an anonymous code block that have been supplied to the function containing the yield statement. yield can take arguments as well.

yield is quite powerful to create enumerators. Let’s try to make the classic Fibonacci sequence as an “endless” enumerator. And then do the same in C#. Both with yield and look at the differences.

Ruby:

fib = Enumerator.new do |obj|
  obj.yield i = 0
  obj.yield j = 1
  while true
    k = i + j
    obj.yield k
    i = j
    j = k
  end
end

20.times { puts fib.next() }

C#:

namespace fib
{
    class Program
    {
        static public IEnumerable<int> Fibs(int size)
        {
            int i = 0;
            yield return i;
            int j = 1;
            yield return j;

            for (int n = 0; n < size; n++)
            {
                int k = i + j;
                yield return k;
                i = j;
                j = k;
            }
        }

        static void Main(string[] args)
        {
            var fibs = Fibs(20);

            foreach (var f in fibs)
            {
                Console.WriteLine(f);
            }
       }
    }
}

When you look at the two examples, there are some major differencies. In Ruby, the yield statement immediatly breaks execution of the code back to the caller's code-block (in this example the Enumerator itself). A state-machine stores all information about what was going on until the yield. So when the enumerator's next() method is called, the execution continues where it left off. This is why the loop in our Fibonacci generator can be infinite.

In C#, however, IEnumerable will run the Fibs function to the end. Each yield return statement will store its argument inside the Enumerable object, which can then later be iterated over. But that also means that you need to make sure that the generating loop exists at some point - hence the size argument.

Inspired by this SO question:

http://stackoverflow.com/questions/8718112/rails-not-fully-compatible-with-postgresqlpostgis-geometry-data-type

I’ve had a lot of trouble recently with Rails and PostGIS. One of the main problem arised with testing. When you run Rails tests (or RSpec for that matter) the test database is always dropped and a new is created. The problem with this is, that the PostGIS extension is not created in this new database. Therefore your schema-load will fail, if you have any postgis-specific fields/indices.

The solution to this is to use a PostgreSQL database template – and of course the activerecord-postgis-adapter found here: https://github.com/dazuma/activerecord-postgis-adapter

First the template:

You need a PostgreSQL template with PostGIS functions support.

Create a template database:

$ psql -U postgres
> CREATE DATABASE template_postgis WITH TEMPLATE=template1 ENCODING='UTF8';
> \c template_postgis;
> CREATE LANGUAGE plpgsql;

Load necessary PostGIS functions into template (your SQL files may be located in a different path, but they come with the PostGIS installation):

$ psql -U postgres -f  /usr/share/postgresql/9.1/contrib/postgis-2.1/postgis.sql template_postgis
$ psql -U postgres -f /usr/share/postgresql/9.1/contrib/postgis-2.1/spatial_ref_sys.sql template_postgis
$ psql -U postgres -f  /usr/share/postgresql/9.1/contrib/postgis-2.1/topology.sql template_postgis

Set database as template and grant permissions:

$ psql -U postgres template_postgis
> UPDATE pg_database SET datistemplate = TRUE WHERE datname = 'template_postgis';
> GRANT ALL ON geometry_columns TO PUBLIC;
> GRANT ALL ON spatial_ref_sys TO PUBLIC;
> GRANT ALL ON topology TO PUBLIC;

Now the adapter:

Add this gem to your Gemfile and run bundle:

gem 'activerecord-postgis-adapter'

After that add the adapter and the template to your config/database.yml like this:

development:
  adapter: postgis
  template: template_postgis
  database: mydb_development

test:
  adapter: postgis
  template: template_postgis
  database: mydb_test

And that should do the trick! Test it by running rake db:schema:dump and rake db:test:prepare.

Let me know, if you get any additional problems regarding this.

Please read this post for my reasons behind this article series.

Some people have asked me, why I try to do things in C# that are clearly Ruby-ideoms. The short answer is: Because I can. The longer answer involves thoughts about that you should never stop learning. For a programmer, this involves pushing your tools to their boundaries and beyond. Seeking new insights other places and apply them to your environment. Stuff like that.

Catch-all property (like Ruby’s method_missing)

One of the powerful features of Ruby is method_missing. With this seemingly innocent construct you are able to make a class respond to things that are not statically defined beforehand.

Typical uses are for ORMs like ActiveRecord, that enables you to map class properties to database table-fields without explicitly defining the fieldnames in your class.

The way ActiveRecord does this is, that the model base-class contains a Hash (Dictionary) called attr. When a table-record is loaded, all fields are loaded into this hash. And method_missing are then used to map property-names directly to keys in the hash.

user = User.find(13)
puts user.email

This can also be done in C# using DynamicObject. http://msdn.microsoft.com/en-us/library/system.dynamic.dynamicobject.aspx

DynamicObject is a rather bold introduction into a strong-typed language like C#, since it expose members such as properties and methods at run time, instead of at compile time.

using System;
using System.Collections.Generic;
using System.Dynamic;

public class MyFakeORM : DynamicObject {
    // For a clearer example, I don't go into the stuff about loading data from the database into this model

    // Dictionary to hold all fields from the loaded record
    Dictionary _attr = new Dictionary();

    // Catch-all methods for getting and setting a "missing" property
    public override bool TrySetMember(SetMemberBinder binder, object value) {
        _attr[binder.Name] = value;
        return true;
    }

    public override bool TryGetMember(GetMemberBinder binder, out object result) {
        return _attr.TryGetValue(binder.Name, out result);
    }
}


Note: For this to work, you also need to define your instance-variable as a dynamic instead of MyFakeORM:

dynamic user = new MyFakeORM();

user.email = "carsten@sarum.dk";

Console.WriteLine(user.email);

If you want to enable access with both properties as shown above AND as a common Dictionary, you need to add setters and getters for the class:

using System;
using System.Collections.Generic;
using System.Dynamic;

public class MyFakeORM : DynamicObject {
    ...

    public object this[string key] {
        get {
            return _attr[key];
        }
        set {
            _attr[key] = value;
        }	
    }	

    ...
    // The rest is as before
}

Now all of the following is valid:

dynamic user = new MyFakeORM();

user.email = "carsten@sarum.dk";
user['email'] = "carsten@sarum.dk";

Console.WriteLine(user.email);
Console.WriteLine(user['email']);

Please read this post for my reasons behind this article series.

Using flash messages between web requests

Ok I admit, this is not entirely a C# vs. Ruby issue. It is more Ruby On Rails done with MVC3. But it uses some of the dynamic stuff from C#.

In Rails you can push messages between requests by using a special flash component:

controller UserController < ApplicationController

def Login
  user = (try-to-login-user)
  if not user.LoggedIn?
    flash[:error] = "Invalid credentials"
    redirect_to :controller => "LoginForm"
  end
end
...

This will use sessions to carry the error-message into the next request. You can now test for the flash-message in LoginForm’s view:

<h1>Login</h1>

<% if flash[:error] %>
  <div class="error"><%=flash[:error]%></div>
<% end %>

After this request, the flash message is erased automatically.

The same thing can be made in .NET by using a combination of the dictionary TempData” and C#’s extension methods. And we can formalize it a bit more by using an enum to control how many different message types, that we will accept.

Create a file called “FlashHelper.cs” with the following content:

using System;
using System.Collections.Generic;
using System.Text;

namespace System.Web.Mvc
{
    public enum FlashType
    {
            Info,
            Warning,
            Error
    }

    public class FlashData
    {
        public FlashType Key { get; set; }
        public string Message { get; set; }
    }

    public static class FlashHelpers
    {
        public static void Flash(this Controller controller, FlashType key, string message)
        {
            if (controller.TempData["flash"] == null)
                controller.TempData["flash"] = new List<FlashData>();

            var flashList = controller.TempData["flash"] as List<FlashData>;
            flashList.Add(new FlashData {Key = key, Message = message});
        }

        public static MvcHtmlString Flash(this HtmlHelper helper)
        {
            var sb = new StringBuilder();

            if (helper.ViewContext.TempData["flash"] != null)
            {
                foreach (FlashData flash in helper.ViewContext.TempData["flash"] as List<FlashData>)
                {
                    sb.AppendLine(string.Format("<div class=\"flash {0}\">", flash.Key.ToString().ToLower()));
                    sb.AppendLine(flash.Message);
                    sb.AppendLine("</div>");
                }
            }
            return MvcHtmlString.Create(sb.ToString());
        }
    }
}

What I am doing here is, that I extend the base MVC controller with a new method called “Flash()”. You call this in your controller to set a new message, supplying the type of message and the message-string itself.

The same goes for extending the Html helper. I define a method, that will print out all added messages, each of them wrapped into their own DIV tag with classes set appropiate of the message type.

So now we can write a C# MVC 3 example like the Rails one above.

The controller:

public class UserController : Controller
{
  public RedirectToRouteResult DoLogin(string username, string password)
  {
    var user = (try-to-login-user);

    if (!user.LoggedIn()) {
      this.Flash(FlashType.Error, "Invalid credentials");
      return RedirectToAction("LoginForm");
    }
    ...

And in your _layout.cshtml view:

@Html.Flash() @RenderBody()

If this example is run, and the user tries to login with invalid credentials, the @Html.Flash() call will render:

<section id="main">
    <div class="flash error">Invalid credentials</div>
    ...
</section>

which you can then style with CSS.

Ruby is a very dynamic language, and you are able to do a lot of stuff with class extensions, meta programming, lambda functions and so forth. When I first experienced Ruby back in 2006 I was very impressed with some of the stuff possible – things that IMHO made C# look stale and static.

Not so any more. The recent updates to C# in 2008 (with .NET 3.5) and lately with .NET 4.0 has added functionality, that enables a more dynamic approach to C# programming, while still keeping the safety net of a strongly typed compiled language.

This is the first part of a small series, where I will take some of the goodies from Ruby and explain how to do it in C#.

Extending classes without subclassing

Most people a first exposed to Ruby through the web framework Ruby on Rails (Rails for short). Rails does a number of cool tricks. One of them is in the ActiveSupport part where the Integer class is extended with some extra methods called days(), weeks(), months(), and years(). This enables some “wow” effects when first looking at Rails code. You are able to do stuff like this:

short_period = 10.days
  => returns a Fixnum with value 864.000 (10 days in seconds)

10.days.to_s
  => returns the string "10 days"

long_period = 3.weeks
  => returns a Fixnum with value 1.814.400 (21 days in seconds)

And even create dates like this

realistic_deadline = 2.weeks.from_now

original_deadline = 5.days.ago

Doing this in C#

This stuff is not originally built into Ruby. The authors of Rails extended the Fixnum class with methods these methods. This is also doable in C#:

public static class IntegerExtensions
{
    public static Days Days(this int days)
        { return new Days(days); }
    public static Weeks Weeks(this int weeks)
        { return new Weeks(weeks); }
    public static Months Months(this int months)
        { return new Months(months); }
}

This introduces 3 new classes, that I will create now:

public class Days
{
    private int days;

    public Days(int d)
        { days = d; }

    public override string ToString()
        { return string.Format("{0} days", days); }

    public DateTime Ago()
        { return DateTime.Today.AddDays(-days); }

    public DateTime FromNow()
        { return DateTime.Today.AddDays(days); }
}

public class Weeks
{
    private int weeks;

    public Weeks(int w)
        { weeks = w; }

    public override string ToString()
        { return string.Format("{0} weeks", weeks); }

    public DateTime Ago()
        { return DateTime.Today.AddDays(-7 * weeks); }

    public DateTime FromNow()
        { return DateTime.Today.AddDays(7 * weeks); }
}

public class Months
{
    private int months;

    public Months(int m)
        { months = m; }

    public override string ToString()
        { return string.Format("{0} months", months); }

    public DateTime Ago()
        { return DateTime.Today.AddMonths(-months); }

    public DateTime FromNow()
        { return DateTime.Today.AddMonths(months); }
}

With these into place I can do this

Console.WriteLine(10.Days().ToString());
Console.WriteLine("{0}", 10.Days().Ago());
Console.WriteLine("{0}", 10.Days().FromNow());

DateTime originalDeadline = 2.Weeks().Ago();

DateTime realisticDeadline = 3.Months().FromNow();

Pretty neat, huh? If only we could loose the parantheses when calling the methods, but I guess we can’t have all. :-)

Continue to part 2.

Skriv et svar

Din e-mail-adresse vil ikke blive offentliggjort. Krævede felter er markeret med *

Disse HTML koder og attributter er tilladte: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>