Getting started with Merb and Datamapper »

Created at: 06.07.2008 02:46, source: Slash Dot Dash, tagged: merb

Merb is the up-and-coming Ruby web framework, designed to improve upon the ideas in Rails whilst being faster, lighter and less opinionated (or more agnostic). I wanted to discover whether it provides any benefits over Rails and what it does differently. The best way to find out; get it installed it and create a new app.

Update: There’s now a much easier way of getting Merb & DataMapper installed.

The official Merb website gives the following simple installation instructions.

sudo gem install merb

However, since I wanted to also try DataMapper as the ORM those instructions failed to install a working setup due to a conflict between Merb and DataMapper dependencies. Unperturbed, I finally got them both installed and working happily together by getting the bleeding edge code from each project’s github repository and following the instructions provided by Mathew Ford’s Living life on the edge. The book is also available on github, you can contribute patches there. Hopefully this issue will be resolved soon enough so that you’ll be able to install the official release gems for both Merb and DataMapper from Rubyforge (instead of running on edge).

Prerequisites

  • You must have git installed (sudo port install git-core using MacPorts on OS X).
  • Remove any older versions of merb (and datamapper) that you might have installed. Use gem list to view local gems and sudo gem uninstall <name> to remove each individual gem.

The Easy Way

Matt’s book outlines an easy way of installing the latest merb & datamapper source, however it failed to properly install the DataMapper gem for me so I had to resort to the hardcore approach.

sudo gem install sake
sake -i 'http://edgy.4ninjas.org/edgy.sake'
sake edgy:install packages="merb-stack"

After installing, to keep up-to-date you just need to execute:

sake edgy:update

Now, if you’re hardcore…

Installing the required dependencies

Start by installing the gem dependancies.

sudo gem install rack mongrel json erubis mime-types rspec hpricot mocha rubigen haml markaby mailfactory ruby2ruby

Installing Merb

Download the merb source:

git clone git://github.com/wycats/merb-core.git
git clone git://github.com/wycats/merb-plugins.git
git clone git://github.com/wycats/merb-more.git

Then install the gems via rake:

cd merb-core ; rake install ; cd ..
cd merb-more ; rake install ; cd ..
cd merb-plugins; rake install ; cd ..

Installing DataMapper

git clone git://github.com/sam/extlib.git
git clone git://github.com/sam/do.git

cd extlib ; rake install ; cd ..
cd do
cd data_objects ; rake install ; cd ..
cd do_mysql ; rake install ; cd ..
cd ..

git clone git://github.com/sam/dm-core.git
git clone git://github.com/sam/dm-more.git

cd dm-core ; rake install ; cd ..
cd dm-more ; rake install ; cd ..

Keeping updated

To update your local gems with the latest code changes you’ll need to do a git pull and then rake install for each of the git repositories previously downloaded.

Creating your first Merb app

You create a new empty Merb app via the merb-gen utility.

merb-gen app demo

(You can also create flattened or single file applications if you wish).

merb-gen app app_name --flat      (for a flattened application)
merb-gen app app_name --very-flat (for a single file application)

As we’re using DataMapper we need to edit config/init.rb and uncomment the use_orm :datamapper line. The next step is to create the database settings file config/database.yml:

---
development: &defaults
  adapter:    mysql
  database:   demo_development
  username:   demo
  password:        p@ssword
  host:       localhost

test:
  <<:         *defaults
  database:   demo_test

production:
  <<:         *defaults
  database:   demo_production

You can now fire up the Merb server to make sure it runs.

$ merb
 ~ Loaded DEVELOPMENT Environment...
 ~ Connecting to database...
 ~ loading gem 'merb_datamapper' ...
 ~ Compiling routes...
 ~ Using 'share-nothing' cookie sessions (4kb limit per client)
 ~ Using Mongrel adapter

Some other useful commands to know:

merb -i                                                        # Interactive merb console

merb-gen model <name>                            # Creates a Datamapper Model stub
merb-gen resource <name>                    # Creates a full resource (incuding model, controller, views & test spec)

rake dm:db:automigrate            # Perform automigration
rake dm:db:autoupgrade            # Perform non destructive automigration

Let’s see how it goes from here with Merb!

Update: There’s now a much easier way of getting Merb & DataMapper installed.


more »

Getting started with Merb and Datamapper »

Created at: 06.07.2008 02:46, source: Slash Dot Dash, tagged: merb

Merb is the up-and-coming Ruby web framework, designed to improve upon the ideas in Rails whilst being faster, lighter and less opinionated (or more agnostic). I wanted to discover whether it provides any benefits over Rails and what it does differently. The best way to find out; get it installed it and create a new app.

Update: There’s now a much easier way of getting Merb & DataMapper installed.

The official Merb website gives the following simple installation instructions.

sudo gem install merb

However, since I wanted to also try DataMapper as the ORM those instructions failed to install a working setup due to a conflict between Merb and DataMapper dependencies. Unperturbed, I finally got them both installed and working happily together by getting the bleeding edge code from each project’s github repository and following the instructions provided by Mathew Ford’s Living life on the edge. The book is also available on github, you can contribute patches there. Hopefully this issue will be resolved soon enough so that you’ll be able to install the official release gems for both Merb and DataMapper from Rubyforge (instead of running on edge).

Prerequisites

  • You must have git installed (sudo port install git-core using MacPorts on OS X).
  • Remove any older versions of merb (and datamapper) that you might have installed. Use gem list to view local gems and sudo gem uninstall <name> to remove each individual gem.

The Easy Way

Matt’s book outlines an easy way of installing the latest merb & datamapper source, however it failed to properly install the DataMapper gem for me so I had to resort to the hardcore approach.

sudo gem install sake
sake -i 'http://edgy.4ninjas.org/edgy.sake'
sake edgy:install packages="merb-stack"

After installing, to keep up-to-date you just need to execute:

sake edgy:update

Now, if you’re hardcore…

Installing the required dependencies

Start by installing the gem dependancies.

sudo gem install rack mongrel json erubis mime-types rspec hpricot mocha rubigen haml markaby mailfactory ruby2ruby

Installing Merb

Download the merb source:

git clone git://github.com/wycats/merb-core.git
git clone git://github.com/wycats/merb-plugins.git
git clone git://github.com/wycats/merb-more.git

Then install the gems via rake:

cd merb-core ; rake install ; cd ..
cd merb-more ; rake install ; cd ..
cd merb-plugins; rake install ; cd ..

Installing DataMapper

git clone git://github.com/sam/extlib.git
git clone git://github.com/sam/do.git

cd extlib ; rake install ; cd ..
cd do
cd data_objects ; rake install ; cd ..
cd do_mysql ; rake install ; cd ..
cd ..

git clone git://github.com/sam/dm-core.git
git clone git://github.com/sam/dm-more.git

cd dm-core ; rake install ; cd ..
cd dm-more ; rake install ; cd ..

Keeping updated

To update your local gems with the latest code changes you’ll need to do a git pull and then rake install for each of the git repositories previously downloaded.

Creating your first Merb app

You create a new empty Merb app via the merb-gen utility.

merb-gen app demo

(You can also create flattened or single file applications if you wish).

merb-gen app app_name --flat      (for a flattened application)
merb-gen app app_name --very-flat (for a single file application)

As we’re using DataMapper we need to edit config/init.rb and uncomment the use_orm :datamapper line. The next step is to create the database settings file config/database.yml:

---
development: &defaults
  adapter:    mysql
  database:   demo_development
  username:   demo
  password:        p@ssword
  host:       localhost

test:
  <<:         *defaults
  database:   demo_test

production:
  <<:         *defaults
  database:   demo_production

You can now fire up the Merb server to make sure it runs.

$ merb
 ~ Loaded DEVELOPMENT Environment...
 ~ Connecting to database...
 ~ loading gem 'merb_datamapper' ...
 ~ Compiling routes...
 ~ Using 'share-nothing' cookie sessions (4kb limit per client)
 ~ Using Mongrel adapter

Some other useful commands to know:

merb -i                                                        # Interactive merb console

merb-gen model <name>                            # Creates a Datamapper Model stub
merb-gen resource <name>                    # Creates a full resource (incuding model, controller, views & test spec)

rake dm:db:automigrate            # Perform automigration
rake dm:db:autoupgrade            # Perform non destructive automigration

Let’s see how it goes from here with Merb!

Update: There’s now a much easier way of getting Merb & DataMapper installed.


more »

News update »

Created at: 18.06.2008 04:40, source: Rails on the Run - Home, tagged: conf merb News rails ruby

I realized I haven't updated this blog in a while. Here is a quick update on what's happened and on things to come:

  • RailsConf 08. Great conference, probably my last Rails Conf though. I'll be in Orlando for Ruby Conf 08 and I'll focus on 1 or 2 local conferences (probably mountain west and another one).

  • MerbCamp 08 in San Diego this Fall organized by SD Ruby. Details are not finalized yet but Yehuda Katz announced it during his Merb talk at RailsConf.

  • Moved this blog to a new Joyent accelerator with git support and finally have the possibility to use Ambition! (planning on moving from Mephisto to Feather)

  • Launched a client's Merb app and getting around 3 million hits/day. Merb is just awesome. (more info when the client's app gets out of beta)

  • I'll join Gregg Pollack from http://railsenvy.com/ during Qcon and take part in the Ruby for the Enterprise track. My talk will focus on Merb usage in real life.

  • Renamed my github username, new repo url: http://github.com/mattetti (sorry about that)


more »

News update »

Created at: 18.06.2008 04:40, source: Rails on the Run - Home, tagged: conf merb News rails ruby

I realized I haven't updated this blog in a while. Here is a quick update on what's happened and on things to come:

  • RailsConf 08. Great conference, probably my last Rails Conf though. I'll be in Orlando for Ruby Conf 08 and I'll focus on 1 or 2 local conferences (probably mountain west and another one).

  • MerbCamp 08 in San Diego this Fall organized by SD Ruby. Details are not finalized yet but Yehuda Katz announced it during his Merb talk at RailsConf.

  • Moved this blog to a new Joyent accelerator with git support and finally have the possibility to use Ambition! (planning on moving from Mephisto to Feather)

  • Launched a client's Merb app and getting around 3 million hits/day. Merb is just awesome. (more info when the client's app gets out of beta)

  • I'll join Gregg Pollack from http://railsenvy.com/ during Qcon and take part in the Ruby for the Enterprise track. My talk will focus on Merb usage in real life.

  • Renamed my github username, new repo url: http://github.com/mattetti (sorry about that)


more »

Avoid using metaprogramming (seriously!) »

Created at: 04.05.2008 11:29, source: Rails on the Run - Home, tagged: benchmark merb metaprogramming speed

Ruby is sexy, Ruby is cool and its metaprogramming potential offers some really cook features. However you might not realize that your cleverness is slowing down your code.

Today I was working on cleaning up merb_helper a Merb plugin that brings a lot of the stuff Rails developers are used to. In Merb we aim for speed and try to avoid magic.

merb_plugin didn't receive a lot of love from the main contributors but few features were added by different contributors and the code became hard to maintain.

Looking at the code I quickly found this bad boy:

(Old Merb Time DSL using metaprogramming)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

   
  module MetaTimeDSL

    {:second => 1, 
     :minute => 60, 
     :hour => 3600, 
     :day => [24,:hours], 
     :week => [7,:days], 
     :month => [30,:days], 
     :year => [364.25, :days]}.each do |meth, amount|
      define_method "m_#{meth}" do
        amount = amount.is_a?(Array) ? amount[0].send(amount[1]) : amount
        self * amount
      end
      alias_method "m_#{meth}s".intern, "m_#{meth}"
    end

  end
  Numeric.send :include, MetaTimeDSL

The above code looks awful to me and I decided to rewrite it a way I thought would be more efficient:

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
33
34
35
36
37
38
39
40
41

  module TimeDSL

    def second
      self * 1
    end
    alias_method :seconds, :second

    def minute
      self * 60
    end
    alias_method :minutes, :minute

    def hour
      self * 3600
    end
    alias_method :hours, :hour

    def day
      self * 86400
    end
    alias_method :days, :day

    def week
      self * 604800
    end
    alias_method :weeks, :week

    def month
      self * 2592000
    end
    alias_method :months, :month

    def year
      self * 31471200
    end
    alias_method :years, :year

  end
  Numeric.send :include, TimeDSL

To make sure I was right, I run the following benchmarks:

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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127

require 'benchmark'
TIMES = (ARGV[0] || 100_000).to_i

Benchmark.bmbm do |x|
  
  x.report("metaprogramming 360.seconds") do
    TIMES.times do    
      360.m_seconds
    end
  end
  
  x.report("no metaprogramming 360.hours") do
    TIMES.times do
      360.seconds
    end
  end
  
  x.report("metaprogramming 360.minutes") do
    TIMES.times do    
      360.m_minutes
    end
  end
  
  x.report("no metaprogramming 360.minutes") do
    TIMES.times do
      360.minutes
    end
  end
  
  x.report("metaprogramming 360.hours") do
    TIMES.times do    
      360.m_hours
    end
  end
  
  x.report("no metaprogramming 360.hours") do
    TIMES.times do
      360.hours
    end
  end
  
  x.report("metaprogramming 360.days") do
    TIMES.times do    
      360.m_days
    end
  end
  
  x.report("no metaprogramming 360.days") do
    TIMES.times do
      360.days
    end
  end
  
  x.report("metaprogramming 360.weeks") do
    TIMES.times do    
      360.m_weeks
    end
  end
  
  x.report("no metaprogramming 360.weeks") do
    TIMES.times do
      360.weeks
    end
  end

  x.report("metaprogramming 18.months") do
    TIMES.times do    
      18.m_months
    end
  end
  
  x.report("no metaprogramming 18.months") do
    TIMES.times do
      18.months
    end
  end
  
  x.report("metaprogramming 7.years") do
    TIMES.times do    
      7.m_years
    end
  end
  
  x.report("no metaprogramming 7.years") do
    TIMES.times do
      7.years
    end
  end
  
end


 Rehearsal ------------------------------------------------------------------
metaprogramming 360.seconds      0.130000   0.000000   0.130000 (  0.133164)
no metaprogramming 360.hours     0.050000   0.000000   0.050000 (  0.042655)
metaprogramming 360.minutes      0.130000   0.000000   0.130000 (  0.133327)
no metaprogramming 360.minutes   0.040000   0.000000   0.040000 (  0.042401)
metaprogramming 360.hours        0.140000   0.000000   0.140000 (  0.134312)
no metaprogramming 360.hours     0.040000   0.000000   0.040000 (  0.043125)
metaprogramming 360.days         0.130000   0.000000   0.130000 (  0.134949)
no metaprogramming 360.days      0.050000   0.000000   0.050000 (  0.043745)
metaprogramming 360.weeks        0.130000   0.000000   0.130000 (  0.135581)
no metaprogramming 360.weeks     0.050000   0.000000   0.050000 (  0.043544)
metaprogramming 18.months        0.130000   0.000000   0.130000 (  0.135234)
no metaprogramming 18.months     0.050000   0.000000   0.050000 (  0.044354)
metaprogramming 7.years          0.140000   0.000000   0.140000 (  0.144062)
no metaprogramming 7.years       0.050000   0.000000   0.050000 (  0.044392)
--------------------------------------------------------- total: 1.260000sec

                                     user     system      total        real
metaprogramming 360.seconds      0.130000   0.000000   0.130000 (  0.132567)
no metaprogramming 360.hours     0.040000   0.000000   0.040000 (  0.042777)
metaprogramming 360.minutes      0.140000   0.000000   0.140000 (  0.132554)
no metaprogramming 360.minutes   0.040000   0.000000   0.040000 (  0.043193)
metaprogramming 360.hours        0.130000   0.000000   0.130000 (  0.133027)
no metaprogramming 360.hours     0.050000   0.000000   0.050000 (  0.042613)
metaprogramming 360.days         0.130000   0.000000   0.130000 (  0.138637)
no metaprogramming 360.days      0.050000   0.000000   0.050000 (  0.043213)
metaprogramming 360.weeks        0.130000   0.000000   0.130000 (  0.134049)
no metaprogramming 360.weeks     0.040000   0.000000   0.040000 (  0.043713)
metaprogramming 18.months        0.140000   0.000000   0.140000 (  0.134941)
no metaprogramming 18.months     0.040000   0.000000   0.040000 (  0.043980)
metaprogramming 7.years          0.150000   0.000000   0.150000 (  0.143389)
no metaprogramming 7.years       0.040000   0.000000   0.040000 (  0.044585)
 0.136591)

The metaprogramming version of the same implementation is almost 3 times slower!

Moral of the story: only use metaprogramming if you really have to or if you don't care about speed of execution.


more »