Channels
Displaying page 3
Posted 8 days ago at The GitHub Blog

Today marks Corey "atmos" Donohoe's first day as a GitHubber. He'll be helping us make GitHub more awesome.

blog.

Welcome to the team, Corey!

back to top
Posted 8 days ago at Engine Yard Ruby on Rails Blog

It is a great time to be a Rubyist. This year we have already seen IronRuby 1.0, JRuby 1.5, with Ruby 1.9 due to be released shortly. Ruby is simply becoming better and faster on every platform. And, wherever Ruby is, Rails is sure to be nearby. Rails 3 looks more awesome each day. Recently, our very own Rubinius officially joined the ranks with a 1.0 release. We are excited to see folks trying it out. All the feedback and issues reported have been a great help. Many people are reporting that their apps "just work". With all this great news, the Ruby world looks rosy indeed. However, we can make Ruby even better. To do so, we need your help. You may not realize this, but the quality of the Ruby code you write can have a significant impact on how great we can make Ruby. I'd like to share some tips about how you can improve your Ruby code while helping us make Ruby better too.

0. Rubinius

Rubinius is a completely new implementation of Ruby. When Evan Phoenix started Rubinius, he put some stakes in the sand. Rubinius has a modern, bytecode virtual machine, a cutting-edge garbage collector, a just-in-time (JIT) compiler utilizing the awesome LLVM project, and a Ruby core library and bytecode compiler written in Ruby. We are only just getting started with 1.0. We have a whole list of features coming, including support for Windows and Ruby version 1.9, as well as improvements to the JIT compiler that should make Ruby several times faster, and removal of the global interpreter lock (GIL) so that your threads will execute Ruby code concurrently. Rubinius does a lot of things differently than MRI under the covers. As Rubinius has grown up, we've definitely seen a wide cross-section of Ruby code while working on features and compatibility. The tips for writing better Ruby code below are based on some of the challenges we have faced.

1. Sending Messages

Rubinius is unique among the various Ruby implementations in that it implements the Ruby core library primarily in Ruby. Even the primitive methods, operations implemented in C++ that must access the virtual machine directly, appear to other Ruby code as normal Ruby methods. Importantly, calling these primitive methods from Ruby code is like calling any other Ruby method. Early on in the Rubinius project, a lot of attention was focused on the idea of Ruby in Ruby. This was a good idea for several reasons, one of which being that Ruby is a more elegant and expressive language than C or Java, and that Ruby programmers tend to understand Ruby code pretty well. This familiarity with Ruby makes Rubinius easier to develop and maintain, and more approachable for many Ruby developers. The validity of these reasons has been demonstrated in the life of the project. However, there are two other very important reasons that don't attract quite as much attention. The first of these is performance. As Evan often points out, Ruby is the currency of the Rubinius VM. It understands Ruby inside and out. The VM knows how to find a Ruby method, how to look up a constant, and what it means for an object to reference another object. The Rubinius VM operates on a special representation of Ruby code. This representation is often referred to as bytecode and is essentially a stream of instructions for the virtual machine. The JIT compiler, which can significantly improve Ruby performance, also operates on bytecode. What this means is that to the JIT, your program and the Ruby core library look an awful lot alike. So much, in fact, that the JIT compiler can mix them all together, which gives the optimizer much greater opportunity to generate really fast code. The second reason is the consistency and elegance of an object-oriented language. When the Ruby core library is written in Ruby, you call a Ruby method, well, by calling a Ruby method. That may sound redundant, but I assure you, it is not. In MRI, for example, with the Ruby core library written in C, the code will often call directly to a C function rather than dispatching normally through Ruby method calls. What this means for you is that MRI may invoke "Ruby" functionality without engaging you in the conversation at all. That inconsistency may prevent you from using simple and elegant object-oriented code that extends the functionality of core classes. In contrast, when functionality is invoked through normal Ruby dispatch, your code can be elegant and participate in the process. However, this is a significant double-edged sword, as we have become painfully aware of in Rubinius. When we implement all the complex behavior of the core library in Ruby, it's quite possible to do something crazy, like remove all the Ruby methods we need to make an object work! That is pretty crazy, right? Fortunately, in this coding wild west, there is a very important principle that can lend some law and order.

2. Liskov Substitution Principle

You may have heard this term tossed around in discussions. If you haven't, don't worry, we'll delve into this fairly intuitive idea. If you have, I hope to renew your commitment and respect for this principle. So, what are we talking about here? Barbara Liskov and her collaborators were concerned with how to write reliable object-oriented software. As you know, one of the principle ideas in class-based object-oriented languages is inheritance, or the relationship between a class and its subclasses. What sort of rules should govern this relationship? What should we expect when we use a subtype in place of a supertype in our program? These are the questions that Barbara Liskov and others were pondering. What they proposed is referred to as the Subtype Requirement, which they defined as:
Let q(x) be a property provable about objects x of type T. Then q(y) should be true for objects y of type S where S is a subtype of T.
(see Behavioral Subtyping Using Invariants and Constraints, by Barbara H. Liskov and Jeannette M. Wing.) Let's consider this in terms of some Ruby code. Suppose you have this class in your program:
  class FancyArray < Array
    def initialize(size)
       # ...
    end
  end
What is wrong with this picture? Well, in my Ruby code, I can do x = Array.new. But what happens when I attempt to use the FancyArray class in place of Array? If I do x = FancyArray.new, I will surely get an ArgumentError exception because FancyArray requires that I pass one argument when calling the new method. Let's phrase this in terms of the Subtype Requirement: Let x be an instance of Array. Then q(x) = the arity of the initialize method is -1. Let y be an instance of FancyArray, which is a subclass of Array. Then q(y) = arity of the initialize method is -1 by the Subtype Requirement. Now let's relate the above to Ruby code and check if the Subtype Requirement holds:
irb(main):001:0> x = Array.instance_method(:initialize).arity
=> -1
irb(main):002:0> y = FancyArray.instance_method(:initialize).arity
=> 1
irb(main):003:0> x == y
=> false
It is clear from this that FancyArray does not conform to the Subtype Requirement. Consequently, code that expects to use an Array will not function correctly when a FancyArray is substituted. It's important to also note that the Subtype Requirement applies to any observable property of the object. The example used in the paper is of a Stack and Queue. Both classes may provide push and pop methods, but the semantics of the methods are quite different between the two classes. Now, you may say, "But, I have a very good reason for requiring an argument to new." Well then, I would venture to say you have an important reason to consider the difference between composition and inheritance for designing your program.

3. Composition versus Inheritance

Of the three object-oriented principles—inheritance, encapsulation, and polymorphism—inheritance has been so abused there could be a 12-step program devoted entirely to it. Fortunately, the remedy for inappropriate use of inheritance is quite simple: compose your objects of other objects. Inheritance models an is a relationship, while composition models a has a relationship. If your object is a String, then it will do all the normal String things just as a String would do them. This is very important. It needs to do String things not just externally, when you call the methods, but internally, when the other String methods call each other. Is your FancyTemplate class really a String? Then, for example, I should always be able to request its length. However, your FancyTemplate instance probably doesn't have a length when it is being built. Therefore, String methods that may be employed during the construction phase could be highly confused. In such case, I suggest your FancyTemplate has a String internally, and it can be urged to give you a representation of that String at some point in time. Yet, it is not a String from the perspective of inheritance and conforming to the Liskov Substitution Principle. Only you can tell whether your model is best represented by inheritance or composition. When designing your classes, be sure to consider the view from inside and out. If you are contorting your methods to act like the class you are inheriting from, perhaps your class only has one of those things, rather than being one of them. Most importantly, remember that you are not the only kid on the playground.

4. Playing Nicely

This is more about general advice than specific admonitions. We are lucky to have such a powerful, expressive language in Ruby. Opening a core class to patch a method is tremendously useful and powerful. However, remember that with great power, comes great responsibility. First and foremost, simply be conscious of what you are asking Ruby to do for you. I used this example earlier, and I'm going to repeat it because in Rubinius we have encountered this more times that we can count. Ruby is an object-oriented language. You cause computation to occur by sending messages to an object. How can the object work if it has no methods? (I say with my best Zoolander impersonation). If your code does:
  class SomeClass
    instance_methods(false).each { |m| undef_method m }
  end
you are (most likely) doing it wrong. There are many variations on this theme, but they all share the same problem: the assumption that those methods you are removing are as superfluous as Johnny's appendix. I assure you, we don't randomly add methods to classes in Rubinius. Again, your code may work fine in MRI when you do this because MRI calls C functions on that object behind your back with impunity. But, we do want to have nice things, right? If you ever wonder what consequences your code may have, just drop into the #rubinius channel on freenode. We will happily discuss it with you. A related problem occurs when code inherits from a core Ruby class and redefines one of the core methods. When the core classes are implemented in Ruby, the methods may depend on one another to perform their tasks. For example, in Hash it would not be entirely unreasonable for each_value to be implemented in terms of each. Well, not unreasonable, that is, until you try to run REXML in the Ruby Standard Library. REXML has an Attributes class that inherits from Hash. The Attributes class then implements an each_attribute method. For good measure, it overrides each to use each_attribute. And each_attribute calls each_value. Waiter, I believe there's a StackError in my Attributes. The moral of the story: the two edges on this wonderful Ruby sword are sharp. It does take extra work to consider how methods on a particular class interact with one another; to some extent, this is an implementation detail. However, it's something to be aware of when you write code. Of course, you can always browse the Ruby implementation of the core classes in Rubinius. Playing nicely is more than being conscientious about how you write your own code. It's also important to consider how you use code others have written. Your code should not depend on implementation details of the classes and libraries you use. However, it's often hard to know what those implementation details are. Often the dependency will be subtle and implicit. Your code will appear to work fine in MRI but break in one of the alternative implementations. There is no general solution to this problem, but you can usually avoid it by checking the assumptions your code makes about the other code it uses. One example of this is mutating a collection in the block passed to an iterating method. Consider the following code:
some_hash.each { |key, value| some_hash.delete(key) if fancy_test(value) }
Hash is a fairly complex data structure and this bit of code can have very different behavior depending on how Hash is implemented. Thankfully, Matz has explicitly said this behavior is undefined.

5. Neighborly C Extensions

While playing nicely in Ruby code is important, it's also very important when writing C extensions. These are programs typically written in C/C++ that directly access the C functions that MRI uses to implement Ruby. You probably regularly use one or more gems or libraries that are partially implemented by a C extension. C extensions are often used to access native libraries from Ruby, for example, when writing database adapters. C extensions are not the only way to access native libraries from Ruby. There are also the FFI and DL libraries. Rubinius was the first implementation to popularize the use of the foreign-function interface (FFI) library for accessing native code. In fact, vital pieces of the core library in Rubinius are implemented via FFI, which is a modern implementation of DL, the dynamic load library that MRI has included for years. There are now quality implementations of FFI available on both JRuby and MRI. FFI is generally the preferred way to interface with native libraries. The benefits include not needing a C compiler and being able to harness the speed or power of a native library while writing pure Ruby code. However, there are still two core use cases for C extensions: 1) when the data marshaling through the FFI layer imposes too large a performance cost; or 2) when your code already relies on an existing C extension. These use cases are hard to get around. Fortunately, we have put a lot of effort into getting C extensions working quite well on Rubinius. In fact, many C extensions just work. However, there is one particular problem with some C extensions that limits our ability to support them: some have explicit dependencies on MRI data structures, for example, RHash. Depending on a data structure your code does not control makes your program vulnerable to breaking if the other code changes its implementation. Unfortunately, the C programming language doesn't do much to enforce good practices here. If the C compiler can see a structure or function in a header file, you are free to use it in your program. Yet, just because you can, does not mean you should. Instead, you should always use a function interface (also known as an API) to access the data. Treat data structures that are not your own as opaque. Of course, that is the ideal world. MRI cannot foretell every use case that a C extension may have. So some of these problems are simply the result of people being more creative than the MRI developers imagined, which is mostly a good thing. In version 1.9, MRI is enforcing the use of API's over raw struct access. For example, rather than using RSTRING(obj)->ptr, your code should do RSTRING_PTR(obj) instead. Since Rubinius is compatible with MRI version 1.8.7, we still support both forms in this case. However, to make your code robust and portable, you should use the RSTRING_PTR API. One thing Rubinius does not support is code like RHASH(obj)->tbl that accesses the RHash struct directly. This is partially because, in Rubinius, Hash is implemented entirely in Ruby. However, most C extension code needs to do something like iterate over the entries rather than just access the structure. In this case, the rb_hash_foreach function is available, so it's quite easy to change a C extension so it will run on Rubinius. In fact, a number of C extensions have already been updated in this way. If you encounter a problem with a C extension, please file an issue for it. We understand there are valid use cases for writing C extensions. While Rubinius is implemented very differently than MRI, we want your C extensions to be able to run in Rubinius and we have worked hard to ensure that most C extensions do run. If you encounter cases where there is no function API to work with MRI data, let us know. We can collaborate with Matz and the MRI developers to add such APIs. That way, you can help us help you to make Ruby better for everyone. Win! Ruby is a terrific language and with your help, it can be even better. Do you have any tips for writing better Ruby code? Please, let us know. If you are new to Rubinius, you may find these previous posts informative:

back to top
Posted 8 days ago at Riding Rails - home

Rails 3.0 is a gift from all of us who’ve worked on it to anyone who wants to build something. If you like our gift, please show it by donating to the Rails 3.0 release charity: Charity:Water. We’ve started a campaign to raise $100,000 in the name of Rails 3.0, which will give 5,000 people access to clean water if we make it.

Charity:Water is a fantastic charity (and not just because they run on Rails!). You’d make everyone working on Rails proud by helping us reach our lofty goal.

Donations can be made at http://mycharitywater.org/rails3.

back to top
Posted 8 days ago at Ruby Inside

RubyDoc.info is a new, automatically updated Ruby documentation site by Loren Segal and Nick Plante that builds upon their earlier success with rdoc.info (which we posted about in 2009). It's powered by YARD, a tool that puts out great looking Ruby documentation (there'll be more about YARD in a post later this week).

RubyDoc.info automatically generates documentation for all gems on rubygems.org (it updates its index once per day) but it does GitHub-hosted projects too. For RubyDoc.info to automatically update with documentation for your Ruby-related GitHub project, use the "Add Project" link on RubyDoc.info and then add http://rubydoc.info/checkout as one of your post-commit hook URLs in your repository's settings - on each future commit, your latest documentation will be built on RubyDoc.info.

back to top
Posted 9 days ago at MongoTips by John Nunemaker

A while back I did an interview with Scout, a monitoring service, on a Scout plugin I helped create for monitoring MongoDB. Sometimes I forget that you all don’t follow my every move and today it occurred to me that I should share it here too.

The plugin has some cool graphs, such as queries per second, index size vs. RAM size, and storage size vs. disk size. Below are a few screenshots of the plugin in action.

I also posted a bit on RailsTips about the plugins before they hit the big leagues and were merged into Scout’s official plugins.

Head over to the Scout blog for the full interview and more details on the plugin.

back to top
Posted 9 days ago at Ruby Inside

RubyKaigi is Japan's "home" Ruby conference and the organizers have just put 27 videos from the RubyKaigi 2010 conference online. Unfortunately I can't link to them individually as they're embedded on a single page, so head over to rubykaigi.tdiary.net and check them out.

Presentation titles include: Ruby 2.0, Ruby API is Improved Unix API, Rocking The Enterprise With Ruby, Mapping the World with DataMapper, The Necessity and Implementation of Speedy Tests, A Metaprogramming Spell Book, Conflicts and Resolutions in Ruby and Rails, and User Experience for Library Designers.

Two caveats: 1) Be aware that some of the presentations are in Japanese (unsurprisingly) although most of the slides include English and, of course, any Ruby is still readable. There were also several English language speakers including Sarah Mei, Carl Lerche, and Jake Scruggs. 2) The player/hosting for the videos seems to be super slow. Give it time and they'll load.

[jobs] Engine Yard are hiring! Did you know that Engine Yard - one of the biggest and brightest companies in the Ruby world - are hiring? They have Ruby Engineer and Ruby App Support Engineer positions open in San Francisco.

back to top
Posted 9 days ago at Intridea - Company Blog

This past weekend was the first Node Knockout, a 48-hour development competition utilizing Node.js. Always up for exploring new technologies, Intridea was represented at the competition by Michael Bleigh, Sean Soper, and Jerry Cheung. 48 hours later, FlockFeeds has launched!

FlockFeed Home

FlockFeeds is a simple tool that will turn your Twitter stream into a news feed. That means that you can simply add the FlockFeed to your RSS reader (such as Google Reader) and FlockFeeds will automatically fetch all of the links that your Twitter network posts, do its best to understand the content and parse out the important stuff, and put it into an easy-to-consume feed for you.

The application is powered by Node.js, Express.js, MongoDB, and Readability.js. Look for a more in-depth technical post in the near future detailing the participants' experiences developing in Node.

Not only did FlockFeeds launch, but we've decided to open up the source code to the public. Feel free to check out the code on GitHub. So give FlockFeeds a try, and don't forget to vote for it in the competition! Voting closes Friday, September 3.

back to top
Posted 9 days ago at Railscasts

If you have frequently changing data on the server side, it's helpful to automatically display this to the user as well. Here I show how to accomplish this with polling in jQuery.

back to top
Posted 9 days ago at lindsaar.net - a different view

You might run into this problem if you are bringing a Rails 2.3 app onto Bundler, specifically, when you try and run “rake cucumber” or just “rake” for RSpec you get an error about missing the constant Rails::Boot::Bundler.

To debug, first make sure you are running the rake task with the bundle exec command just to make sure that you are using the correct gems:

$ bundle exec rake

Which gave me the following output:

(in /users/mikel/Code/app)
/users/mikel/Code/app/config/Gemfile not found
rake aborted!

OK, so it can’t find the Gemfile, so running trace on this doesn’t really give any more data, just a long stack trace. However, we do know that in a Rails 2.3.x application, the Gemfile location is setup in the config/initializers/preinitializer.rb file, so lets look in there:

begin
  require "rubygems"
  require "bundler"
rescue LoadError
  raise "Could not load the bundler gem. Install it with `gem install bundler`."
end

if Gem::Version.new(Bundler::VERSION) <= Gem::Version.new("0.9.24")
  raise RuntimeError, "Your bundler version is too old for Rails 2.3." +
   "Run `gem install bundler` to upgrade."
end

begin
  # Set up load paths for all bundled gems
  ENV["BUNDLE_GEMFILE"] = File.expand_path("../../Gemfile", __FILE__)
  Bundler.setup
rescue Bundler::GemNotFound
  raise RuntimeError, "Bundler couldn't find some gems." +
    "Did you run `bundle install`?"
end

Yep, that’s a stock standard preinitializer from gembundler.com, however if you look at about line 15, it is trying to pull in the Gemfile from a location relative to the current directory, perhaps RSpec is changing this somehow before the preinitializer is run?

To test this out, we change line 15 to be:

  ENV["BUNDLE_GEMFILE"] = File.expand_path(File.join(Rails.root,"Gemfile"), __FILE__)

And then run our rake task again, and see lots of green dots. Awesome :)

I’ve sent off a patch to gembundler.com to get this fixed there for future reference.

blogLater

Mikel

back to top
Posted 9 days ago at MongoTips by John Nunemaker

An astute follower of this blog (and MongoDB) will remember that back in February, Boxed Ice posted their Notes from a Production Deployment.

Earlier this month, they posted another great article, this time on Automating partitioning, sharding and failover with MongoDB.

The article covers setting up replica sets, adding to the set, and setting up sharding (from config server to adding shards). There are even a couple screen casts showing how to get things going.

back to top
Posted 9 days ago at MongoTips by John Nunemaker

Kristina Chodorow has a good post on the assumptions that MongoDB makes. There are 5 in all. MongoDB assumes…

  • that you have a 64-bit machine.
  • that you’re using a little-endian system.
  • that you have more than one server.
  • you want fast/unsafe, but lets you do slow/safe.
  • assume you’ll complain if something goes wrong.

The last 3 are my favorites. You should have more than one server. You control speed/durability (more on single server durability here). You should let them know if things do not work as expected.

Those points seem obvious, but they are good reminders. Be sure to read If it quacks like a rdbms… for details on each of the 5 points.

back to top
Posted 9 days ago at Ruby Inside

Rails 3.0 has been underway for a good two years, so it’s with immense pleasure that we can declare it’s finally here. We’ve brought the work of more than 1,600 contributors together to make everything better, faster, cleaner, and more beautiful.

David Heinemeier Hansson

DHH rings the bell and announces that Rails 3.0 (final) has been released after two years of determined effort by the Rails core team. Grab it now with gem install rails --version 3.0.0 or, if you're in no rush, Rails 3.0.1 might come along within a week or two.

The Videos

DHH gives a quick roundup of some of Rails 3's new features but like Emma Watson's head PhotoShopped onto yet another naked body, it's nothing you haven't seen before. If you're really fresh to Rails 3.0, though, Gregg does an admirable job of boiling everything down into a digestible format with his (free!) Dive Into Rails 3.0 screencast series:

Ryan Bates has also produced a fistful of his typically succinct but precise RailsCasts videos on a wide array of Rails 3.0 topics. Ryan always focuses on code and practicalities so these are a good place to start if you want to follow along and do some coding yourself:

If you don't like videos, still follow the links, because there are links to the ASCIIcasts regular HTML versions of the Railscasts videos. These are regular blog posts that you can follow at your own pace.

And a book - in German

Oh, and if you speak German, check out this "Ruby on Rails 3" book by Michael Voigt and Stefan Tennigkeit. Michael e-mailed me and claims it's the first complete Rails 3.0 book to hit the presses.

back to top
Posted 9 days ago at Riding Rails - home

Rails 3.0 has been underway for a good two years, so it’s with immense pleasure that we can declare it’s finally here. We’ve brought the work of more than 1,600 contributors together to make everything better, faster, cleaner, and more beautiful.

This third generation of Rails has seen thousands of commits, so picking what to highlight was always going to be tough and incomplete. But here’s a choice selection of major changes for Rails 3:

New Active Record query engine
Active Record has adopted the ARel query engine to make scopes and queries more consistent and composable. This makes it much easier to build complex queries over several iterations. We also delay the actual execution of the query until it’s needed. Here’s a simple example:

users = User.where(:name => "david").limit(20)
users.where("age > 29")

# SELECT * FROM users 
# WHERE name = "david" AND age > 29 
# ORDER BY name
# LIMIT 20
users.order(:name).each { |user| puts user.name }

Read more in new Active Record guide and watch the Dive into Rails 3: ARel video.

New router for Action Controller
When we switched to a REST-based approach for controllers in Rails 2, we patched on the syntax to the existing router while we were waiting to see if the experiment panned out.

It did and for Rails 3 we’ve gone back and revamped the syntax completely to favor the REST style with less noise and more flexibility:

resources :people do
  resource :avatar

  collection do
    get :winners, :losers
  end
end

# /sd34fgh/rooms
scope ':token', :token => /\w{5,5}/ do
  resources :rooms
end

# /descriptions
# /pl/descriptions
# /en/descriptions
scope '(:locale)', :locale => /en|pl/ do
  resources :descriptions
  root :to => 'projects#index'
end

Read more in the new routing guide.

New Action Mailer
Action Mailer was born with a split-personality of half model, half controller. In Rails 3, we’ve made the choice to make it all controller. This means that the feel and functionality will be much closer to Action Controller and in fact they now share a bunch of underlying code. Here’s a taste of what it looks like now:

class Notifier < ActionMailer::Base
  default :from =>
    "Highrise <system@#{APPLICATION_DOMAIN}>" 

  def new_project(digest, project, person)
    @digest, @project, @person = digest, project, person

    attachments['digest.pdf'] = digest.to_pdf
    attachments['logo.jpg']   = File.read(project.logo_path)

    mail(
      :subject => "Your digest for #{project.name}",
      :to => person.email_address_with_name
    ) do |format|
      format.text { render :text => "Something texty" }
      format.html { render :text => "Something <i>texty</i>" }
    end
  end
end

The new Action Mailer is built on top of the new Mail gem as well. Say goodbye to TMail headaches.

Read more in new Action Mailer guide.

Manage dependencies with Bundler
Managing all the dependencies of a Rails application has long been a hassle of patchworks. We had config.gem, Capistrano externals, custom rake setup tasks, and other incomplete solutions.

Bundler cleans all that up and allows you to specify the libraries, frameworks, and plugins that your application depends on. All Rails 3 applications are born with a Gemfile to control it all. See more on the Bundler site.

XSS protection by default
The internet is a scary place and Rails 3 is watching out for you by default. We’ve had CRSF protection with form signing for a while and SQL-injection protection since the beginning, but Rails 3 ups the anté with XSS protection as well (hat tip to Django for convincing us).

See the Railscast on XSS video and the Dive into Rails 3: Cross-site scripting video for more.

Say goodbye to encoding issues
If you browse the Internet with any frequency, you will likely encounter the � character. This problem is extremely pervasive, and is caused by mixing and matching content with different encodings.

In a system like Rails, content comes from the database, your templates, your source files, and from the user. Ruby 1.9 gives us the raw tools to eliminate these problems, and in combination with Rails 3, � should be a thing of the past in Rails applications. Never struggle with corrupted data pasted by a user from Microsoft Word again!

Active Model: Validations, callbacks, etc for all models
We’ve extracted quite a bit of commonly requested Active Record components into the new Active Model framework. This allows an ORM like Mongoid to use Active Record’s validations, callbacks, serialization, and i18n support.

Additionally, in the rewrite of Action Controller, we removed any direct references to Active Record, defining a clean, simple API that ORMs can implement. If you use an API-compliant ORM (like DataMapper, Sequel, or Mongoid), you will be able to use features like form_for, link_to and redirect_to with objects from those ORMs without any additional work.

Official plugin APIs
We also rewrote Railties with the express goal of using the new plugin API for all Rails frameworks like Active Record and Action Mailer. This means that Rails plugins like the ones for DataMapper and RSpec have access to all of the integration as the built-in support for Active Record and Test::Unit.

The new Railtie API makes it possible to modify the built-in generators, add rake tasks, configure default Rails options, and specify code to run as early, or as late as you need. Rails plugins like Devise were able to add much better integration in the Rails 3 version of their plugin. Expect to see a lot more of that in the months ahead.

Rewritten internals
We rewrote the internals of Action Pack and Railties, making them much more flexible and easier to extend. Instead of a single monolithic ActionController::Base, Rails 3 exposes a number of modules, each with defined APIs, that you can mix and match to create special-purpose controllers for your own use. Both Action Mailer in Rails and the Cells project make heavy use of this new functionality.

You can also take a look a this blog post by Yehuda (from last year) to see how the new architecture makes it easy to implement Django-style generic actions in Rails by leveraging Rack and ActionController::Metal.

The Rails generator system is got a revamp as well. Instead of monolithic generators that know about all of the Rails frameworks, each generator calls a series of hooks, such as :test_framework and :orm, that plugins can register handlers for. This means that generating a scaffold when using rSpec, DataMapper and Haml will generate a scaffold customized for those plugins.

Agnosticism with jQuery, rSpec, and Data Mapper
The rewritten internals and the new plugin APIs have brought true agnosticism to Rails 3 for all components of the framework. Prefer DataMapper to Active Record? No problem. Want to use jQuery instead of Prototype? Go ahead. Eager to test with rSpec instead of test/unit? You got it.

It’s never been easier to Have It Your Way™ with Rails 3. And at the same time, we’ve made that happen without making using the excellent default stack any more complicated.

Documentation
Rails 3 has had a long development cycle and while that might have lead to some impatience, it has also given book and tutorial authors a chance to catch up and be ready. There’s a wealth of great Rails 3 documentation available already and more is coming shortly.

The Agile Web Development with Rails 4th Ed book is almost ready and there are plenty more books coming. Check out all the new guides, the new official videos, new Railscasts, and a new tutorial. See the recent recap of documentation sources for more.

Installation
gem install rails --version 3.0.0.

We also have a Rails v3.0.0 tag and a 3-0-stable branch.

Rails 3.0 has been designed to work with Ruby 1.8.7, Ruby 1.9.2, and JRuby 1.5.2+.

Gratitude and next steps
I’m personally incredibly proud of this release. I’ve been working on Rails for more than 7 years and the quality of the framework we have today is just astounding. This is only possible as a community effort and Rails 3 has seen so many incredible developers step up and help make this our best release ever (wink). Many thanks to all of you.

We’ll continue to develop Rails 3.0 with fixes and tweaks via the stable branch and Rails 3.1 is already cooking on master.

back to top
Posted 10 days ago at Ruby Inside

EuRuKo is the brand of Europe's principal Ruby conference series and EuRuKo 2010 took place in late May. Why, then, am I posting about it in August? First, I'm a strong supporter of EuRuKo and promised to post a roundup of the event here. Secondly, it turns out it took a while for the videos to all be uploaded ;-) Third, I've taken my time in getting round to it. Nonetheless, there are some amazing presentations you can watch and they're still fewer than three months out of date!

One of the event's organizers, Ela Madej, gives a summary:

European Ruby Conference 2010 is now well over and the Berlin EuRuKo 2011 team are surely working on their opening song for the next year. Yes, we all know they sing well - their uber-strong German vocal was nothing but adorable.

Despite the flooding and changing the conference venue just one week before the event, EuRuKo was great! It was filled with fantastic talks and Rubyists from all over the planet. Here are some numbers: around 121 Poles (less than half of all 280 attendees), at least 40 Germans, Rubyists from Japan, Austria, Spain, UK, Switzerland, Uruguay, USA, Cuba, Slovakia, Czech Republic, Slovenia, Croatia, Estonia, The Netherlands, Latvia, Italy, France, Belgium, Brasil and more.

For everyone who missed the event, the videos from the conference are on Vimeo. There is also a great summary of the talks for Day One and
Day Two. Here are the links to EuRuKo official photos on Flickr for Day One and Day Two also.

Ela Madej

While there are 37 videos on offer, some standouts include:

EuRuKo is supported by not only by Rubyists paying to attend but by quite a few sponsors, with 2010's event no exception. The organizers asked me to specially thank their biggest sponsor Novelys - a team of French Ruby on Rails experts. On top of that, EuRuKo's afterparty sponsors were Applicake and Lunar Logic Polska, two Ruby development teams from Poland. Finally, 16 micro sponsors helped out too.

I've been a keen supporter of EuRuKo since the first event so a big thanks to all of the sponsors and attendees for supporting Ruby's principal Ruby conference. Now, go enjoy those videos.

back to top
Posted 10 days ago at Riding Rails - home

To this day I still hear people complain that Rails has poor documentation. From where I’m sitting this seems far from the truth. Let me lay out the evidence piece by piece:

RailsTutorial.org

To learn Rails from scratch Michael Hartl recently finished his book Ruby on Rails Tutorial: Learn Rails by Example. The book teaches Rails 3 from the ground up and it’s available for FREE online. If you’d rather have a PDF or a book you can grab that as well (and he’s even working on some screencasts).

The source for the finalized book will be pushed to GitHub and released under a Creative Commons License shortly after Rails 3 is done. If you’d like to help translate the book to your language of choice, feel free to contact Michael and he’ll get in touch when it’s time to make it happen.

Rails Guides

If you’re not a Rails newbie don’t forget about the Rails Guides, which have been updated for Rails 3.

Rails API Docs

There are two main websites I use to do API lookups. The first is Rails Searchable API Doc, which has online and offline searchable documentation. The second is APIdock which is online only, but has the ability to comment and easily compare different versions of documentation.

Rails 3 Free Screencasts

If you’re more of a visual learner (like me) then there are plenty of free screencasts to teach you about Rails 3. About 2 months ago I produced the Rails 3 Screencasts, which will get you started.

Ryan Bates has also produced an incredible amount of Rails 3 screencasts over on Railscasts.com. Ryan has been producing Railscasts for over 3 1/2 years, isn’t that crazy?

There’s also a few good free screencasts over on Teach me to Code by Charles Max Wood.

Audio Podcast Resources

If you find yourself wondering how to keep up with all of the newest features / libraries for Rails 3, both the Ruby5 Podcast and the Ruby Show are going strong. Don’t listen to audio? It doesn’t matter, just subscribe to the Ruby5 RSS feed and get links with descriptions to all the newest libraries, tutorials, and more. You might also want to checkout Peter Cooper’s new Ruby Weekly, a Ruby email newsletter.

Need to upgrade a big app to Rails 3?

Jeremy McAnnaly’s Rails 3 Upgrade Handbook PDF for just $12. There’s also a few paid screencasts for the upgrade over on Thinkcode.tv and BDDCasts.

Need a Book?

There’s a bunch of books that will be coming out after the release, most of which you can start reading now. The Rails 3 Way by Obie Fernandez, Rails 3 In Action by Ryan Bigg and Yehuda Katz, and Beginning Rails by Cloves Carneiro Jr and Rida Al Barazi.

In conclusion

No more complaining about lack of good documentation! Seriously. If you want even more Rails 3 content, check out the blog post by Kevin Faustino on 34 Ruby on Rails 3 resources to get you started.

back to top