Reasoning for not supporting ruby 1.8.6 in Rails 3.0

I've seen it mentioned in a couple of places that Rails 3.0 is not
going to be supported on ruby 1.8.6. Considering that 1.8.6 is the
still the most popular version of ruby, this seems odd. Has the final
decision been made on this? If so, could someone explain the
reasoning behind this decision (if it's been explained elsewhere, a
link would be fine)? If not, is there anything that contributors can
do to ensure that Rails 3.0 is supported on ruby 1.8.6?

Jeremy

I believe this was discussed in passing in the CI thread? Something
along the lines of Hash#hash in 1.8.6 being a problem for us.

On another level though, 1.9 is the future of ruby, and 1.8.7 is
expressly intended to be the 1.8.x which makes it easier to handle the
migration. So preferring 1.9 and supporting 1.8.7 seems consistent
with that?

Assuming the community provides patches that allow Rails to continue
working on 1.8.6, would the core team consider supporting 1.8.6?

To put it another way, if there aren't hard technical problems in
supporting 1.8.6, why force 1.8.7 down the community's collective
throat?

Jeremy

Assuming the community provides patches that allow Rails to continue
working on 1.8.6, would the core team consider supporting 1.8.6?

To put it another way, if there aren't hard technical problems in
supporting 1.8.6, why force 1.8.7 down the community's collective
throat?

My understanding is that there *are* hard technical problems present
today. Yehuda and jeremy have more info, and perhaps the relevant
problems can be backported to 1.8.6 making this a non-issue.

I don't think anyone wants to prematurely abandon a functioning ruby,
however we also don't want to continue supporting older interpreters
forever. Even if we do support 1.8.6 for 3.0, the end of the line
*is* coming, and we'd be best off preparing for that rather than
attempting to hold back the tide of progress.

Assuming the community provides patches that allow Rails to continue
working on 1.8.6, would the core team consider supporting 1.8.6?

To put it another way, if there aren't hard technical problems in
supporting 1.8.6, why force 1.8.7 down the community's collective
throat?

My understanding is that there *are* hard technical problems present
today. Yehuda and jeremy have more info, and perhaps the relevant
problems can be backported to 1.8.6 making this a non-issue.

Hopefully Yehuda or Jeremy can take a moment to explain what the problems are.

I don't think anyone wants to prematurely abandon a functioning ruby,
however we also don't want to continue supporting older interpreters
forever. Even if we do support 1.8.6 for 3.0, the end of the line
*is* coming, and we'd be best off preparing for that rather than
attempting to hold back the tide of progress.

I think as long as ruby 1.8.6 is officially supported in terms of
backporting patches and security fixes (which Kirk Haines of EY is
handling), it's a valid candidate for Rails support.

FWIW, Rails currently supports ruby 1.8.2
(http://rubyonrails.org/download), so there is precedent for
supporting interpreter versions that are 4 years old.

Jeremy

Hey Jeremy,

I apologize for the delay.

The basic idea is that there are a number of issues in Ruby 1.8.6 that are simply not going to be fixed (see http://svn.ruby-lang.org/repos/ruby/tags/v1_8_7/ChangeLog for a complete list), and targeting 1.8.6 means always having to make sure that new features are not implicated by those old bugs. Sure, the community could spend a lot of time and energy writing a (slow and brittle) shim, but that would mean that the community would be forced to do that every time we ran into a new issue. Also, since Rails major releases come out around once every two years, choosing to stick with 1.8.6 now would mean we’d be stuck with 1.8.6 until approximately 2012. Given the number of bugfixes in 1.8.7, I’d really not have to do that.

Some bugfix examples include:

  • Hash#hash, #eql and Array#hash, #eql: Both of these do not include recursive Hashes, which means they cannot be used as Hash keys internally in 1.8.6. This significantly impedes our ability to use the only caching primitive available in Ruby. For instance, we use a Hash to cache template lookup for [“template_name”, {:formats => [:html], :locale => [:en]}, “controller_name”, partial?]. In order to correctly shim this in 1.8.6, every template lookup would be forced to do an expensive in-Ruby calculation that would almost entirely negate the cache. I’ve done a significant amount of performance work in Rails 3, and this issue constantly crops up.

  • A ton of improved Windows support, especially for files. Both Pathname and File have a significant number of improvements to improve Windows issues. This is an area where being able to rely on more correct behavior will avoid bugs that could have otherwise happened and might have ended up uncaught. These bugs are almost always subtle, and don’t always show up in CI (that is, once we have reliable Windows CI).

Additionally, there are some new features that we’d like to be able to use at some point.

  • Enumerators. The Rack API requires an object that respond_to?(:each) as the body. Since Enumerators use that same API, there is potentially an opportunity for simplification and optimization using this API. I would like to be able to experiment with this feature, which is very hard to emulate (especially with exact fidelity), in 1.8.6.

  • Improved information for error messages. Kernel#method and Kernel#callee have been added, which provide us with some information we can use to present better error messages. Additionally, Method and UnboundMethod now have #name and #owner, which give us more information about methods than we had before, and can permit us to provide better error information.

  • Native String#chars and #instance_exec. These are emulated ok in Rails for Ruby 1.8.6, but the native versions are significantly better, more performant, and less flaky, and being able to rely on the native implementation would be convenient. This is obviously less important than the bugfixes above.

Finally, Ruby 1.8.7 does not appear to provide backward-compatibility issues. For instance, WePlay, which has a significant, complex app, had a lot of trouble porting their app to Ruby 1.9, but basically zero problems with Ruby 1.8.7. The few issues that people did have were rapidly and diligently resolved by the Ruby team. Do you have any reason to believe otherwise?

– Yehuda

The EY team will maintain 1.8.x branch only for security issues, I don’t think they will backport all the 1.9.x features. Because it’s a non-sense. The present (not the future) of Ruby it’s 1.9.1, honestly don’t know why the majority (myself included) is still on the old-and-beloved 1.8.6.

The “Big Rewrite” could be a great moment to cleanup the code from the ugly version check (RUBY_VERSION), and at the same time, as you know, you have to change something in your code to jump into Rails 3. Why don’t spend more time to move to the newest Ruby?

The Rails community provides a fundamental and continuos feedback to Matz and his team, and actually we aren’t so useful for that cause.

Many people are scared by the gems compatibility, and it’s right, but if we don’t evolve and take the courage, will be always blocked in this kind of limbo. When Rails 3 will be released, nothing will change, you app will not stop to work, you don’t have to migrate immediately, you can take all the time to do it.

One of the roles of a Core Team is to take decisions thinking about the future. Till a couple of years ago people was scared to embrace Ruby/Rails for several reasons, the VM, the lib compatibility, the hosting support. But we simply won. I don’t see the problem. We just need to roll up our sleeves and get more involved in this process.

Luca

The present (not the future) of Ruby it's 1.9.1, honestly don't know why the majority (myself included) is still on the old-and-beloved 1.8.6.

Our primary reason is because none of the main hosting services support 1.9. EngineYard, Rails Machine, etc. all are still on 1.8.6. We are ready to move to 1.9 if our hosts supported it.

The way I see it, any argument for continuing support for 1.8.6 are the same arguments that can be used to support not upgrading to Rails 3.

I'm fully in support of pushing forward in the hopes that forward movement will prompt the rest of the ecosystem to move forward.

thanks,
-Chad

You can also check the REE status on passenger website. This is the
only reason people want 1.8.6 anymore. They are looking for donations,
to fund performance optimizations. More importantly what's stopping
the ruby community as a whole to move forward with these REE
contributions in 1.9? I don't understand this.

dreamcat4
dreamcat4@gmail.com

You can safely use Passenger with Ruby 1.9.1, avoiding REE.

  • Luca

I wasn't asking whether you can use Passenger with 1.9.1. I'm talking
the about these REE announcements on the passenger (sorry, 'Phusion')
website: http://blog.phusion.nl/2009/05/27/ruby-enterprise-edition-third-sponsorship-campaign/

My point is that for many outside the development loop, its not
particularly clear if / when the Ruby 1.8.6 REE optimisations were
added to 1.9.1. So many people still insist on installing 1.8.6 rather
than moving forwards. The whole project situation between ruby1.9 and
REE, their respective project statuses could be clearer.

dreamcat4
dreamcat4@gmail.com

Yehuda,

First, thank you very much for your detailed post. I don't have any
reason to believe that migrating to 1.8.7 will be difficult. It's
just that running on 1.8.7 makes it more likely that I'll accidently
use features that aren't supported on 1.8.6, and I want other
libraries I develop (mainly Sequel) to support 1.8.6.

I'm glad that Rails 3 is requiring ruby 1.8.7 for technical reasons
and not just to try to push the community in a certain direction. It
doesn't look like it would be worth it to try to support ruby 1.8.6 in
Rails 3.

Thanks,
Jeremy

Hey Jeremy,
I apologize for the delay.
The basic idea is that there are a number of issues in Ruby 1.8.6 that are
simply not going to be fixed

First, thank you very much for your detailed post. I don't have any
reason to believe that migrating to 1.8.7 will be difficult. It's
just that running on 1.8.7 makes it more likely that I'll accidently
use features that aren't supported on 1.8.6, and I want other
libraries I develop (mainly Sequel) to support 1.8.6.

The answer to this is to test your code against multiple versions.
There are tools such as multiruby (part of ZenTest) which make this
easy. I currently test my ri_cal gem against 1.8.6, 1.8.7 and 1.9.1

I'm glad that Rails 3 is requiring ruby 1.8.7 for technical reasons
and not just to try to push the community in a certain direction.

I think it's more of a pull than a push.

I still think that 1.8.6 needs to live on, only because there are
still apps out there with dependencies (like old Rails versions) which
require it, for which migration to a newer version is not justifiable.

For a new app, particularly one written to Rails 3, I'd probably just
start with Ruby 1.9. I'm still not convinced that 1.8.7 is either
fish or fowl.

I think if we don't go to ruby 1.9, ruby and rails will get stuck in a
similar thing that happened with java 1.2 1.4 and 1.5.

Come on guys, these are all open source projects. If something isn't
working on a newer version, how much work would it be to get it to
work?

just my 2cents

Certainly, supporting the latest version of ruby is a good thing.
However, forcing people to upgrade their ruby installation without a
solid technical reason is a bad practice to get into. If people want
to use 1.9, it should be on 1.9's own merits, not simply because Rails
is forcing them to.

At some point, there may be technical reasons that make it difficult
to support the then current version of Rails on ruby 1.8.x, just as
there are current technical reasons that make it difficult to support
Rails 3 on ruby 1.8.6. Until that point, Rails should support both
1.8.x and 1.9.x, IMO.

Jeremy

The rub with that is that you end up with a lowest common denominator. A bunch of new features in 1.9 which aren't used because of backward compatibility. Pretty soon we're where Perl is with library code that's huge with version conditionals strewn through it.

I don't understand the issue. If someone wants to stick with 1.8.x then why not also stick with Rails 2.x?

The "solid technical reason" is that developers have finite amounts of time, I'd rather that limited amount of time is spent on high value activities. Offering options for people not willing to upgrade (for no solid technical reason) seems like a low value activity to me.

I think if we don't go to ruby 1.9, ruby and rails will get stuck in a
similar thing that happened with java 1.2 1.4 and 1.5.

Certainly, supporting the latest version of ruby is a good thing.
However, forcing people to upgrade their ruby installation without a
solid technical reason is a bad practice to get into. If people want
to use 1.9, it should be on 1.9's own merits, not simply because Rails
is forcing them to.

Nobody is forcing anyone to upgrade to Rails 3 either.

At some point, there may be technical reasons that make it difficult
to support the then current version of Rails on ruby 1.8.x, just as
there are current technical reasons that make it difficult to support
Rails 3 on ruby 1.8.6. Until that point, Rails should support both
1.8.x and 1.9.x, IMO.

You can only kick so many old cans down the road for so long.

There's a cost of maintaining compatibility with old versions of
anything, it's not just 1.8.x and 1.9.x, it's 1.8.6.x, 1.8.7.x, 1.9.x
and soon apparently 1.8.8.x.

And it's not just Rails, it's all the various gems, plug-ins, etc.
That's a major reason making the transition to 1.8.7 and more so to
1.9.x was difficult. 1.8.7 introduced syntax changes which required
some amount of compatibility patches, 1.9 introduced a superset of
those syntax changes along with a new internal implementation which
broke gems with C extensions, this is gradually being addressed,
either by bringing old gems and plugins along or by replacements
providing the same or more function.

From what I understand, the plan for Rails 3 is to provide support for
1.8.7+, and I think that that's the right thing to do, in order to
allow Rails, Ruby and the sea of open source which comprises the Ruby
landscape progress and evolve.

Come on guys, these are all open source projects. If something isn't
working on a newer version, how much work would it be to get it to
work?

I'm not sure if you're being sarcastic here, but I'll bite. It's very often quite a bit of work. It's even more work to then maintain 1.8.6 and 1.8.7 compatibility once you do it.

While, as I've already stated, I think supporting 1.9 is very important - please don't minimize the effort that it will take everyone in the community to do it.

thanks,
-Chad

Has anyone tried installing the mysql gem from Rubyforge on 1.9? It’s stuff like that that makes people hesitant to switch to 1.9. Projects on Rubyforge who’s owners have long abandoned it. There needs to be a way for other people to patch gems and submit them and have a team of dedicated people to approve them for when they become abandonware.

I have a working* version of the MySQL gem on Github under my account.

  • This means it compiles, and I won’t claim it to be bug free.

There is that ERB comment issue, whereby it turns out (according to
the official documentation) that we were not actually allowed to write
things like:

  <% elsif customer.oddball? # we get lots of these guys %>

which is pretty widely used and worked perfectly just fine most or all
of the way through the 1.8.6 series but doesn't on 1.8.7 (see
http://www.ruby-forum.com/topic/154835 and
https://rails.lighthouseapp.com/projects/8994/tickets/955-ruby-187-and-erb-problem-3).

This is a really nasty one because, really, there's no reason why this
shouldn't be made to work, and when it stops working, it doesn't
break.... you just lose a whole big chunk of output from your views.
A bit silent and nasty for many of us.

The Ruby guys don't seem to be inclined to change it back, so unless
one already has full test coverage for each and every case/path in
every one of your views files, this is something important to scan for
when upgrading to 1.8.7.

You could get an approximate test with just grep if you're careful
about the conditions (for example, <%# this is a legitimate ERB
comment %> but <% # this isn't %>, and be careful about multiple
blocks on one line), so if you are moving the whole team to 1.8.7 and
so just need to do a once-over pass, that's probably fine.

But that will tend to produce false alarms, for example if you have
other uses of hashes on the same line, such as <% s =
'/test.html#anchor' %>, so it's not much help if you want an automated
test to run in continuous integration or need to audit a large number
of views. I'm knocking up a bit of code to do it properly using
ruby-parser, if people are interested I'll sort out a good way to
package and release it.