Acts as Conference - Day 1

February 8, 2008

The first day of Acts as Conference is in the books. I'm not going to give a full summary of each presentation, just a couple of highlights that I remember. The first thing is that I won the Engine Yard 3 slice configuration for one year giveaway! I'm super excited about that, but as everyone said to me throughout the day "What are you going to use it for? Something good I hope!". I think I've got an idea for something good, but we'll see.

First off, Ezra gave a talk on Merb. It was mostly a repeat of stuff for me, although it was good to hear some of the ideas about the refactoring towards a 1.0 release.

Next up was Evan Phoenix. He gave a talk about Rubinius, which I believe, as do many others, is the future de facto ruby interpreter. More than just that, it will open up a world other world of possibilities.

Although I love the idea of Rubinius, the most interesting parts of Evan's talk weren't about Rubinius specifically. First, he talked about how sometimes when you are banging your head against the desk trying to come up with the best solution for some complex problem, the best thing to do can be put on your iPod and take a walk:

The unconscious mind is a better problem solver than the conscious mind

That's a good quote. The other point I took away from his talk is his philosophy about how to build a vibrant community for an open source project. For Rubinius, his idea has been that any person that commits even the smallest patch gets commit rights. The idea is that you want to "hook developers in with a small patch". Once you get them in doing small things, they will feel like it is fun and they are invested in the project and they will go on to contribute more substantial features.

Evan and Ezra's talks got me motivated to get involved. During lunch I discovered and reported a small Merb bug and then submitted a patch for it, which was accepted and merged in. Michael Ivey's "So you want to contribute to Merb" article was very helpful in figuring out how to get involved.

After that was Neil Ford's presentation on Advanced DSLs in Ruby. One neat technique I picked up from this is how to use instance_eval to remove repetitive calls to an object. Say you have this:

class Foo
  attr_accessor :foos
  def add(s)
    @foos ||= []
    @foos << s
  end
end

foo = Foo.new
foo.add "bar"
foo.add "bang"
foo.add "baz"
puts foo.foos

To avoid calling foo mutliple times, you can refactor that out like this:

class Foo
  attr_accessor :foos
  def initialize(&block)
    @foos = []
    instance_eval &block
  end
  def add(s)
    @foos << s
  end
end

foo = Foo.new do
  add "bar"
  add "bang"
  add "baz"
end
puts foo.foos

It seems contrived in this example, because it is, but this can definitely be useful when creating internal DSLs.

I liked his definition of internal vs. external DSLs. Internal DSLs are DSLs that you write on top of a host language, like Ruby, whereas an external DSL is a DSL that is parsed, meaning you take a string, parse it and then do something. Based on that definition, I don't like the terms internal and external DSLs because of the implications that come along with that. I think the terms "Hosted" vs. "Parsed" DSLs would be much clearer. Just because it's an internal DSL doesn't mean that you can't expose it to end users. The whole point of a DSL is to allow end users to define things like business rules. Neil's opinion is that external DSLs can be more flexible, but are usually harder to develop and evolve, but there are tools coming out to make that easier, so keep an eye out for that.

The next talk was Luke Francl. Someone asked him a question about pair programming and I think he had a good point, which was that pair programming stops developers from goofing off. The example he gave is that when you are programming by yourself, you might say "I'll take 5 seconds to check out Reddit", which inevitable turns into 5 minutes. You're not likely to do that with someone else sitting right next to you. It's true. I think a thing to add is that pair programming acts as real time code review. In my experience, code review never happens, so pair programming is good way to get that. It is also a good way to get developer buy in. Sometimes you might have a developer create something by themselves and then another developer sees it and says to themselves "WTF, why would he do that this way!". If you are there when the code gets written, you wil have a discussion with the developer, so you will have that understanding, or possible have a better way to do it.

Next up was Peter Armstrong, who talked about getting Flex/Air to work with Rails and how he is working on a framework called Ruboss, which is a simpler alternative to Carnigorm. Personally I don't think I'll be doing any Flex-related stuff in the near future, I'll probably be looking into ExtJS to try to create a rich user experience. I don't like the idea of writing code in ActionScript and then compiling it. I'd rather either write code in JavaScript or have the option of generating the JavaScript dynamically with a "hosted" DSL written in Ruby.

Lastly Dan Benjamin wrapped up the day with a talk about simplicity and focusing on the user experience. It was a nice talk to cap off a day of technical talks. I'll definitely be thinking more about simplicity and the user experience on my upcoming projects.

Posted in Technology | Tags Merb, Ruby, Rails | 8 Comments

Merb and Data Mapper

November 16, 2007

A couple of new frameworks making waves in the Ruby community are Merb and Data Mapper. Merb and Data Mapper seem to go together like peanut butter and jelly in that Merb gives you pretty much everything Rails gives you except for an ORM framework, and Data Mapper is an ORM framework like Active Record.

Data Mapper has a fantastic Why Data Mapper? page. I love this page because it assumes you the reader are a Ruby on Rails web developer, so you know Active Record, and you want to know why you'd want to use Data Mapper instead of Active Record. After reading that page, I was definitely intrigued. It's amazing what good documentation can do for the success of a framework. Merb has documentation on the differences between Merb and Rails as well.

The most obvious difference that jumps out at you between Active Record and Data Mapper is that in the Data Mapper, you define the properties (a.k.a fields, attributes, columns) of your models inside the model itself, as opposed to Active Record, where you define no properties in your model and reflect the properties from the columns in your database. This has long been a point of contention for many developers critical of Rails.

The most obvious difference between Rails and Merb is that with Merb, controller actions always return the data that is to be sent to the client. A Merb action can simply return a String, or it could return a File, and IO or even a Proc. That sounds cool.

It will be interesting to see if Merb/Data Mapper gain popularity in the Ruby community. Rails is a full-stack solution, where as Merb is a MVC framework and leaves it up to you to choose an ORM framework and Data Mapper is just an ORM, not tied to any one MVC framework. This is more like the Java web framework world, where you have MVC frameworks like Struts, Stripes, etc. and ORM frameworks like Hibernate, and you glue them all together with something like Spring or Guice. The difference here is that you glue them together with Ruby, still no XML or Annotations needed.

One thing I thought I liked about Rails is that it's the only web framework people in the Ruby community use to build web apps. In the Java world, managers and business types would say "We're a Java shop" or "We're building our app in Java", but the reality is that there are so many different frameworks and saying you are building it in "Java" could mean one of a hundred different things. That might really mean "JSF/Struts 2/Spring/Hibernate" or "Freemarker/Stripes/Guice/iBatis". Matt Raible has basically built his entire career around analyzing all the different options there are for Java web frameworks, as well as developing a meta-framework to help tie them all together. Up until now, on the Ruby side of things, if someone says we're building an app with Ruby on Rails, you know what you are talking about.

But it seems this could be the start of trend, where we get more frameworks within the Ruby community, which is a good thing because you can make choices, but on the other hand it could start to fragment the community. Overall I think it's a win and the reality you come to realize after developing with Rails for a year or so is that Ruby is really the thing that makes the whole thing go and that knowledge is easily portable to other Ruby frameworks. To make it even easier, Merb and Data Mapper both have many of the same concepts as Rails, so I can't imagine the learning curve of switching from one to the other to be particularly steep.

Another crazy idea is that with specialized frameworks like Merb and Data Mapper that are meant to be just one part of a stack rather than the full stack like Rails, and JRuby becoming a legitimate option, you could start to see some weird hybrid Ruby/Java apps, like Merb+Hibernate, or Stripes+Data Mapper. I doubt that would be common, but you could do it.

So talk is cheap, let's get something going. To install Merb and Data Mapper, I followed these instructions for setting up Merb and Data Mapper.

sudo gem install merb --include-dependencies
sudo gem install datamapper
sudo gem install ruby2ruby --include-dependencies
sudo gem install merb_datamapper
cd /usr/local/lib/ruby/gems/1.8/gems/datamapper-0.2.3
sudo bash -c "ARCHFLAGS='-arch i386' rake dm:install:mysql"

Believe it or not that actually worked for my on my Macbook. That last step just outputs the following if it works:

(in /usr/local/lib/ruby/gems/1.8/gems/datamapper-0.2.3)

Here's to hoping I can just do this at some point in the future:

sudo gem install merb_datamapper_mysql --include-dependencies

But you can't for now. So I continued following the instructions and got this error when I tried to run rake:

paulbarry@paulbarry: ~/projects/foo $ rake
(in /Users/paulbarry/projects/foo)
Using pure ruby JSON lib
rake aborted!
no such file to load -- json/pure
/Users/paulbarry/projects/foo/rakefile:10
(See full trace by running task with --trace)

Why didn't gem install merb --include-dependencies install json and json_pure for me if they are required dependencies? Good question, I don't know, but we'll just install them now to get things going:

sudo gem install json json_pure

So after that, everything goes off without a hitch. Picking up where the instructions left off, let's at least create a hello world app. Create a file in app/controllers called hello_world.rb with the following contents:

class HelloWorld < Application
  def index
    "<h1>Hello, World!</h1>"
  end
end

Go to http://localhost:4000/hello_world and bask in the glory of your fist Merb web application. This should seem familar, except for the fact that you are naming it HelloWorld instead of HelloWorldController. How do you avoid namespace collisions when you have a User controller and a User model? Good question, I'll let you know when I find the answer.

So as promised, you can just return a string and that's when gets rendered in the browser. But you don't want to do that for real, so let's render a template. Create a file app/views/hello_world/index.html.erb and put the html in there. Change the index method to just call render, like this:

class HelloWorld < Application
  def index
    render
  end
end

And there's our hello world with a template. Ok, so what about data mapper? So step one is create file in app/models called foo.rb with the following contents:

class Foo < DataMapper::Base
  property :bar, :string
  property :created_at, :datetime
  property :updated_at, :datetime

  validates_presence_of :bar
  validates_length_of :bar, :minimum => 1
end

This also should make sense if you are Rails developer. The only difference is that we are defining our properties in the class, rather than in a migration. To create our table and a test record, start the merb console, which you do by executing merb -i, and then enter these commands:

irb(main):004:0> DataMapper::Base.auto_migrate!
=> [Foo]
irb(main):005:0> Foo.create(:bar => 'Hello, World!')
=> #<Foo:0x22c5964 @new_record=false, ...

Ok, so them we modify our controller and view to use this:

class HelloWorld < Application
  def index
    @foo = Foo.first
    render
  end
end

and:

<h1><%= @foo.bar %></h1>

And there we go, Merb and Data Mapper working together as one.

Posted in Technology | Tags Merb, Ruby, Rails, DataMapper | 18 Comments

<< Newer Articles