Today, I sat down with Yehuda Katz, Rails Framework Architect. Katz used to be the man behind Merb, but when Merb was merged into Rails last January, Katz became a core Rails contributor and architect. I sat him down to talk about the recent Rails 3.0 beta, and about the new life within the Ruby on Rails community.
How have things been on Rails since the merge with Merb?
It's been good. The interesting thing that's happened since that is a lot of other Ruby projects have done it. There's a tool called Webrat, which is a full stack testing tool; and abstraction around HTML Unit. Someone said I can make it better, they called it Capybara, and they pushed it into Rails.
Also, Micronaut. It's basically guys who said 'we can do rspec better.' This has started to happen in the Ruby community, and it makes me happy. I think there is too much in the open source world of people building software because you want to put your name back out there.
That's been a positive outcome. Also the Rails core team diversity has been very helpful. Rails core, before, was 37Signals and some people doing client work. Now we have people doing custom development around it. We have people working on problems we didn't have before. It's definitely caused us, both people who are new and veteran contributors, to question our assumptions. The conclusions have been almost 100% positive.
The community has gotten a lot healthier since the merge. Like rails was getting stagnant a lot of people who are coming back now who are coming to rails to first contribute. A big chunk of the time I spend every day on rails is cat herding. And trying to balance the need to be involved in the architecture of the thing, and getting things done by real people interested in doing things.
I hear things are being uncoupled, starting with Prototype.
Unobtrusive JavaScript. Rails is no longer coupled to Prototype. That was a community effort. DHH tweeted 'we're running behind,' and a community formed out of the aether. Less than a week later it's all done.
Basically what Rails did before, when you said 'link to remote,' like, I want a link that when you click if makes an AJAX request and when it comes back, put it in a div. In Rails on click, you would have to go through and find all those places where you used Prototype and remove that reference . People made shims they got out of sync. The way it works in Rails 3 it's straight HTML: a href = “actual url” and it uses the HTML 5 data tag. It supports custom attributes. We've created a library that says 'find any links and wire them up.' Anybody else in other libraries like Dojo who want this benefit just have to write JavaScript and not ruby.
Before having someone go and hack in the helpers and such required someone on both sides of the fence at all times.
What are the biggest changes for Rails 3.0?
The biggest thing is security. We went through the known remaining security vulnerabilties based on having spoken to Twitter and having them say 'your security tools are too manual right now.' [To prevent cross-site-scripting vulnerabilities] Almost every framework says if you use user content, just escape it. It's easy to forget to escape it. As an attacker, you have to find the places in Web applications where they forgot to escape. What we've essentially done is made Rails pessimistic by default. If you try to put in a string into HTML at any time, we automatically escape it. We went through all of Rails' internals and marked the form tags as safe, which means that for the vast majority of cases, users won't have to do a lot. But there will be cases where they were relying on content input by the user that was unsafe. But it's now almost impossible to have an accidental XSS attack.
We've also gone into cross-site request forgery (CSRF) protection. We were pretty rock solid before, but there were cases where we were blacklisting things which were not vectors for an attack. We made it less annoying to work with the systems. If there was a form you were submitting with JavaScript, you had to form a token even though that was not a possible vector. This makes it less likely for people to turn [CSRF protection] off.
Tthe second big thing is improving interoperability, mainly with other Ruby libraries. We've gone through Rails systematically, and found where we were coupling ourselves to ourselves and removed those. Rails controller view code is no longer coupled to the models, so you can use any views you want. We also added support other templating languages. We made it a lot easier to support other testing frameworks. TestUnit was standard, and others had to do a lot of work to strip out our support for TestUnit and add their own. Using rspec felt worse than using TestUnit. TestUnit itself is a plug-in now.
How has Jruby been involved in the Rails 3.0 push?
The biggest thing is to be in touch with them and make sure Rails 3 ran on JRuby. We made significant changes, and a lot of the things we added to Rails 3 were shaped a lot by JRuby and Charlie [Nutter, co-creator of JRuby]. Charlie wants to allow existing Hibernate models to work within Rails. That's not going to ship with Rails, but the way we built it, it's possible to swap in something for using Hibernate.
We didn't go in and say 'we're supporting some Java feature.' They have top notch Java integration. Because of the fact that we've made our layers agnostic, it's really easy to work with JRuby. We will see things, Hibernate being the first obvious example that will highlight this interoperability.
It sounds like there's a lot of new monitoring options in 3.0.
We've instrumented the entire framework. Ruby itself is intrinsically insturmentable. You can do something before and after to call the other method first. Then you have people trying to find the appropriate place to insert. For rails 3 we wanted ot make it really easy for New Relic [A new Rails company focused on monitoring] to exist. We rearchitected the logger to, instead of being hardcoded inside parts of Rails, to listen to instrumentation events and do the right thing. Things like, 'started SQL now.' Server did a request and it took this amount of time: that info is collected. If you want to say 'this should be considered model time,' you could do that yourself.
What's going on with Active Record versus DataMapper?
Active record got a big boost in Rails 3. There are a lot of reasons why people might have used DataMapper, before, and it is now in Rails. Active Record has a relational data model, so it is now a lot easier to chain together queries an compose queries. DataMapper is still a great library, with support for multiple databases. We wanted DataMapper to have the same mount of support as Active Record.
Another [area of improvement around DataMapper and Active Record] is that configuration for plug-ins looked different than configuration for top level things. In Rails 3, we just expose the ability for anyone to have just top level configuration. Finally, [we improved] instrumentation. Instead of the logger saying 'how much time is Active Record saving?' Active Record emits a SQL event and the logger listens for a SQL event, collects all the events, and puts them in the log. Anybody else who wants to put in a piece of Rails can do that now. DataMapper doesn't look different from using Active Record in the logs.
Finally initialization. On boot, plug-ins were initialized later. Active Record hooked in early, plug-ins like DataMapper could not. In Rails 3, Active Record is loaded similarly to how DataMapper is loaded. We also added an API for saying 'I would like to run this after that.' I want to run this block after or before this block. This makes it easier for frameworks that look at the built in code.
The default Rails experience is the same.
This sounds like it's mostly a housekeeping release.
I call it the Snow Leopard release. The routers way better; you can route based on sub-domains. Ruby has racks, like portlets were an abstraction, this is a simpler abstraction and Rails is now basically a rack framework. If you want to take a Sinatra application and put it inside a Rails route, it's really easy.
So, what's with Sinatra? It seems to be getting popular.
Sinatra is essentially a nicer wrapper around rack. You receive a request which is a hash and pathinfo, and you return an array of status code, the headers, and the body, and you have to do very specific things. That's not complicated; it's fairly easy, but most of the time you want to say when the user goes to this URL I want you to return this.
Sinatra makes that workflow really easy, especially if you have one big library you want to expose to the Internet. We've been looking at whether or not those abstractions will work in Rails. In general, it would require some work to get working. Our template API is very performant. But the way you set it up is--not horrible--but could be better. We're looking at ways to leverage the ideas of their templating system in Rails and maybe creating handlers. But in order to do that we have to solve some performance problems. We're looking at that for 3.1.
What do you think about other Web frameworks in other languages, like Django in Python?
We're trying to make it so that if people want to build something in other places, you shouldn't have to make a Rails specific version. Django wants people to write Django-specific things, not just Python. What's really cool about Ruby is that there isn't any divide. We pushed a lot of stuff back to rack, a lot to Ruby Gems; we prefer it to have things in a sharable form. People who work on minor frameworks write a disproportionate code. Making it easy to share template stuff with Sinatra, even though there's only 100 users--what good could that be? Well, if we are sharing, we have a much better ecosystem. The Python world has this wrong. Django feels that because they are a big framework, they don't have to share.
Do you even get to code anymore?
I do get to code. Half my time is working with people. Almost all the time I spend working with people is code reviews. It would be fairly difficult for the people who I work with who are not on Rails core to do stuff on their own, but a lot of people are getting pulled in. We have a few people contracted at Engine Yard who have worked their way into being members of the core team. The goal is not to make us [the core team] obsolete, but to make us a big group.ac