Setting charset with a before filter in Sinatra 2

Posted by Jonas Elfström Fri, 31 Jul 2009 06:30:00 GMT

In the git example in my previous post about Sinatra and Heroku I happened to mention a filter for using UTF-8. I remember finding it somewhere on the net but I can't remember where and it seems my current google-fu is as weak as my memory. Anyway, it looks like this:

1
2
3
4
5
6
7
8
9
10
11
CONTENT_TYPES = {:html => 'text/html', :css => 'text/css', 
                :js  => 'application/javascript'}

before do
 request_uri = case request.env['REQUEST_URI']
   when /\.css$/ : :css
   when /\.js$/  : :js
   else          :html
 end
 content_type CONTENT_TYPES[request_uri], :charset => 'utf-8'
end

An average application in the clouds

Posted by Jonas Elfström Thu, 11 Jun 2009 21:03:00 GMT

A couple of days ago I published my first applicaiton "in the cloud". I named it Average and it's only a tiny little app that I did for fun and learning. It's written in Ruby with the micro framework Sinatra, DataMapper, Haml and published to Heroku with their git-based workflow. Except Ruby I hadn't used any of these before.

The tools
Sinatra will most likely become my favorite tool for quick web hacks in the futute. I've been using Rubys' built-in CGI support for such before, but Sinatra is beyond compare. It may not be very well suited for anything but small projects but it's hand in glove for admin pages, "reports" or REST services. Still there are some not that small projects on http://www.sinatrarb.com/wild.html

DataMapper is an ORM and at glance it looks a lot like ActiveRecord but it feels more "pure". I really like that it uses regular Ruby classes (and methods, no method_missing magic) that you include DataMapper to. Sadly the documentation is terrible, it's unstructured and missing some crucial bits. Hopefully that will change in the near future and since it's a wiki anyone can help.

Haml is a markup language that generates HTML/XHTML. It makes it very easy to create fully validating XHTML pages. Some parts of Hamls felt kind of strange but after using it for a couple of hours it all seemed to fall into place and I started to like it more and more by the minute. As a disclaimer I have to admit to only have created 8-9 simple Haml templates ever.

git is a distributed revision control tool. It's really fast, faster than any SCM I've ever used. Git was initially developed by Linus Torvalds and http://github.com/ seems to be a driving force of adoption.

Heroku is very impressive! Unparalleled ease of deployment and if you need more power just slide the "dyno slider"! Heroku is free as long as you only use one dyno, but if you need more "CPUs", backups, more than 5MB and so on, there's a fee.

Under the hood
Average doesn't do much but to its defense it does it in few lines of code. One single Ruby file and some views:
$ wc -l average.rb
  196 average.rb
$ wc -l views/*.haml
  6 views/average.haml
 19 views/index.haml
 25 views/new.haml
  9 views/notenoughdata.haml
 13 views/poll.haml
 16 views/show.haml
284 rows total.
And there's nothing more to it because the data model is included in the average.rb:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Average
  include DataMapper::Resource
  property :id, Integer, :serial => true
  property :name, String, :length => 50
  property :unit, String, :length => 50
  property :what, String, :length => 50
  property :public, Boolean, :default => true
  property :avgthreshold, Integer, :default => 0
  property :cryptokey, String
  property :adminkey, String
  property :allow_multiple, Boolean, :default => false
  has n, :values
end

class Value
  include DataMapper::Resource
  property :id, Serial
  property :value, Float
  property :valuekey, String
  belongs_to :average
end


I only had to type one single SQL statement:
CREATE DATABASE average;
The tables were created by executing DataMapper.auto_migrate! (in irb), it's also possible to migrate table by table: Average.auto_migrate!. Migrate drops the table so if you want to keep the data you can use Averages.auto_upgrade!. It's real easy and powerful.
Heroku also has a console and there you can run Ruby code in the running production enviroment.
$ heroku console
>> DataMapper.auto_migrate!

To push your local database to the server just:
$ heroku db:push mysql://user:pwd@localhost/average
(Heroku runs PostgreSQL but the above translates from a plethora of databases. I got some kind of problem with Booleans from MySQL though.)
For ActiveRecord there's rake db:...

A typical Sinatra Route (a HTTP method paired with a URL matching pattern) could look something like this:

1
2
3
4
get '/' do
  @avgs=Average.all(:public => true, :limit => 25, :order => [:id.desc])
  haml :index
end


My views are written in Haml and it looks something like this:

1
2
3
4
%h1= @avg.name
%p== The average #{@avg.what} is #{average} #{@avg.unit} and the sample size is #{sample_size}.
- if @done==false then
  %a{:href=>"/poll/"+@avg.cryptokey} Add value


Heroku uses git to publish the applications and the workflow is:
git add.
git commit -m "added a before filter for charset utf-8"
git push heroku

PS. Peter, look, it validates! http://validator.w3.org/check?uri=http%3A%2F%2Faverage.heroku.com :) DS

No var for me in the foreach

Posted by Jonas Elfström Tue, 09 Jun 2009 20:24:00 GMT

In C# 3.0 we got type inference or implicit typing as Microsoft likes to call it. As a Ruby programmer I've got a thing for essence over ceremony and those repetive declarations in C# (and Java) has always bothered me. So of course I quickly put var in my tool belt. If I want to create a certain object why should I have to state that twice?

1
2
3
4
// C# 2.0
Dictionary<Customer, List<PhoneNumber>> phonebook = new Dictionary<Customer, List<PhoneNumber>>(); 
// C# 3.0
var phonebook = new Dictionary<Customer, List<PhoneNumber>>();

Still you should use it with care. I've seen:

1
2
var i = 5;
var s = "This stmt is unprovable!";

And frankly, I do not agree.

A couple of days ago I almost thought I found a bug or limitation in the C# compiler. Something like the following would not compile:

1
2
3
4
5
6
7
String html = "<a href='http://is.gd/Uoip'>Recursion</a>,\r\n" +
              "see <a href='http://is.gd/Uoip'>recursion</a>.";
String links="";
var matches = Regex.Matches(html, "(a href=')(.*)('>)");
foreach (var match in matches) {
    links+=match.Groups[2]+"\r\n";
}

The compiler complained that Object had no Groups method. How come it could not see that Regex.Matches returned a MatchCollection and that that collection was populated with Match objects? Then it dawned on me. Back in the dark ages of C# 1.x we did not have generics. MatchCollection is an old class that implements ICollection and not ICollection(T) so the compiler could not infer the type. A quick change to:

foreach (Match match in matches) {

and we were good to go.

Get the value of and with using the null-coalescing operator

Posted by Jonas Elfström Fri, 15 May 2009 22:38:00 GMT

I like the ?? operator that surfaced in C# 2.0. I'm often in environments where null values florish and ?? is a great way to handle them, especially for presentation. A while ago I found a use for the ?? operator in a way I'd never used it before.

The problem at hand was to return an account number from data that could be described as somewhat inconsistent.

The application had left room for the users to enter accounts in two by two ways. A customer could have multiple subsidiaries and in each subsidiary, by misconception, two different fields had been used as the account number. It was also possible to connect an account to all subsidairies of a customer at the same time as a specific subsidiary of that customer had an account defined.

Only if a unique account could be found it should be returned. All other cases should return a cause of failure so that the users could use that information to clean up the mess.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
private static Account GetCustomerAccount(Customer customer)
{
  bool hasAccount = !String.IsNullOrEmpty(customer.AccountNo);
  bool hasAccountNoExtra = !String.IsNullOrEmpty(customer.AccountNoExtra);
  bool hasAllSubsAccount = !String.IsNullOrEmpty(customer.AccountNoAllSubs);
  bool hasAllSubsAccountNoExtra = 
       !String.IsNullOrEmpty(customer.AccountNoExtraAllSubs);
  var account = new Account();

  if ((hasAccount || hasAccountNoExtra) &&
      (hasAllSubsAccount || hasAllSubsAccountNoExtra)) 
  {
    account.Status = account.HasBothAllSubsAndSpecific;
    return account;
  }
  if ((hasAccount && hasAccountNoExtra) ||   
      (hasAllSubsAccount && hasAllSubsAccountNoExtra)) 
  {
    account.Status = account.HasBothAccountAndAccountExtra;
    return account;
  }

  account.AccountNo = customer.AccountNo ??
                      customer.AccountNoExtra ??
                      customer.AccountNoAllSubs ??
                      customer.AccountNoExtraAllSubs;

  if (account.AccountNo==null)
    account.Status=account.HasNoAccountDefined;

  return account;
}


Notice how AccountNo is set to the first non null value of the four. Imagine that with plain ifs. Here I believe the ??-operator both makes the code clear and saves us from a bunch of nested ifs.

Breaking good

Posted by Jonas Elfström Sun, 03 May 2009 21:24:00 GMT

Check out Chris Eng's post on how he broke the code on the cover of the 2009 Verizon Data Breach Investigations Report. He makes it seem so simple and without making a big deal of it he also shows the tools and commands he used.

Older posts: 1 ... 4 5 6 7 8 ... 12