From: Yehuda Katz Date: 2009-11-17T06:48:42+09:00 Subject: [ruby-core:26774] Ruby constant lookup --00c09f9c98fdcece41047883f4f2 Content-Type: text/plain; charset=ISO-8859-1 Over the past six months or so, I have been working with the new Ruby 1.9 constant lookup rules. The rules change constant lookup from being _always_ lexically scoped, to changing when *_eval is used. This change has produced some of the most serious challenges to getting Rails working (and continuing to work) on Ruby 1.9. At least one reason is that it makes DSLs harder to build, and Rails has a number of useful DSLs that it uses. Another is that it causes abstraction pain. For instance, you can do the following in Rails: module ActionController::MimeResponds extend ActiveSupport::Concern included do inheritable_accessor :responder, :mimes_for_respond_to, :instance_writer => false self.responder = ActionController::Responder clear_respond_to end end This is a wrapper around the very common: def self.included(klass) klass.class_eval do # code here end end However, because it uses a block, it forces us into the Ruby 1.9 constant lookup scheme. In this case it is not that big of a deal (ActionController::Responder is not much worse than Responder), but even in this case most users would expect to be able to use constants available in the lexical scope. And indeed, since it works that way in Ruby 1.8, significant code is created with that expectation, _which passes_ when tested with Ruby 1.8. Matz, I spoke with you and Koichi about this at Ruby Kaigi, and showed you some other real-world examples of breakage. I would like to raise this issue again in light of the fact that this has been, by far, the biggest real-life difficulty in making Rails 1.9 compatible. Because I understand the utility in the Ruby 1.9 approach, I would like to suggest that users be allowed to choose which scoping they want. I suggest that module_eval, by default, revert to Ruby 1.8 behavior. I also suggest that we add a new method (or flag to module_eval) to enable the new behavior. Thank you, Yehuda Katz Developer | Engine Yard (ph) 718.877.1325 --00c09f9c98fdcece41047883f4f2 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable
Over the past six months or so, I have been working with the new Ruby = 1.9 constant lookup rules. The rules change constant lookup from being _alw= ays_ lexically scoped, to changing when *_eval is used.

This change has produced some of the most serious challenges to gettin= g Rails working (and continuing to work) on Ruby 1.9. At least one reason i= s that it makes DSLs harder to build, and Rails has a number of useful DSLs= that it uses. Another is that it causes abstraction pain.

For instance, you can do the following in Rails:
<= div>
module ActionController::MimeResponds
=A0=A0ex= tend ActiveSupport::Concern

=A0=A0 =A0included do<= /div>
=A0=A0 =A0 =A0inheritable_accessor :responder, :mimes_for_respond_to, :inst= ance_writer =3D> false
=A0=A0 =A0 =A0self.responder =3D Action= Controller::Responder
=A0=A0 =A0 =A0clear_respond_to
= =A0=A0 =A0end
end

This is a wrapper around the very common:
def self.included(klass)
=A0=A0klass.class_eval do
=A0=A0 =A0# code here
=A0=A0end
end
<= br>
However, because it uses a block, it forces us into the Ruby 1.9 constant l= ookup scheme. In this case it is not that big of a deal (ActionController::= Responder is not much worse than Responder), but even in this case most use= rs would expect to be able to use constants available in the lexical scope.= And indeed, since it works that way in Ruby 1.8, significant code is creat= ed with that expectation, _which passes_ when tested with Ruby 1.8.

Matz, I spoke with you and Koichi about this at Ruby Ka= igi, and showed you some other real-world examples of breakage. I would lik= e to raise this issue again in light of the fact that this has been, by far= , the biggest real-life difficulty in making Rails 1.9 compatible.

Because I understand the utility in the Ruby 1.9 approa= ch, I would like to suggest that users be allowed to choose which scoping t= hey want. I suggest that module_eval, by default, revert to Ruby 1.8 behavi= or. I also suggest that we add a new method (or flag to module_eval) to ena= ble the new behavior.

Thank you,=A0

Yehuda Katz
Dev= eloper | Engine Yard
(ph) 718.877.1325
--00c09f9c98fdcece41047883f4f2--