[ruby-core:26774] Ruby constant lookup

1 vaatamine
Liigu esimese lugemata sõnumi juurde

Yehuda Katz

lugemata,
16. nov 2009, 16:48:4216.11.09
kuni ruby-core
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

Shugo Maeda

lugemata,
16. nov 2009, 21:41:4716.11.09
kuni ruby...@ruby-lang.org
Hi,

At Tue, 17 Nov 2009 06:48:42 +0900,


Yehuda Katz <wyc...@gmail.com> wrote:
> 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

Do you mean that `self.responder = ActionController::Responder' can be replaced
by `self.responder = Responder' on Ruby 1.8?

Then, does it really work on Ruby 1.8?
I guess MimeResponds should be nested in ActionController as follows:

module ActionController
module MimeResponds
...
end
end

> > This is a wrapper around the very common:
>
> def self.included(klass)
> klass.class_eval do
> # code here
> end
> end

For Matz and Koichi (and other people who aren't familiar with Rails),
included and append_features are overridden in ActiveSupport::Concern
as follows:

def included(base = nil, &block)
if base.nil?
@_included_block = block
else
super
end
end

def append_features(base)
if super
...
base.class_eval(&@_included_block) if instance_variable_defined?("@_incl
uded_block")
end
end

> 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.

I basically prefer the behavior of Ruby 1.9. I think class variables
should especially be lookuped like Ruby 1.9 because they can't be
accessed outside of a class or its instance. Then, I guess your
problem may be able to fixed differently.

The problem is not that Ruby 1.9 prepends the receiver of class_eval to
the constant lookup path, but that a wrapper of class_eval can't be
implemented on Ruby 1.9.

The following program works on both Ruby 1.8 and 1.9:

class Foo
end

module ActionController
Responder = "This is a Responder"
module MimeResponds
Foo.class_eval do
p Responder
end
end
end

However, the following program doesn't work on Ruby 1.9:

def my_class_eval(klass, &block)
klass.class_eval(&block)
end

class Foo
end

module ActionController
Responder = "This is a Responder"
module MimeResponds
my_class_eval(Foo) do
p Responder
end
end
end

It's because class_eval prepends the reciver to the constant lookup
path at the time of invocation of class_eval. I think it should
prepends the receiver to the constant lookup path which the given block
holds.

I have attached a patch to fix it. If it's acceptable, I'll write a
test and commit them.

--
Shugo Maeda <sh...@ruby-lang.org>

class_eval.diff

Yehuda Katz

lugemata,
16. nov 2009, 23:18:2916.11.09
kuni ruby...@ruby-lang.org
Shugo,

I agree that we should have both, but I think that the lexical scope case should win. Consider the case of RSpec:

describe "Date" do
  it "equals itself" do
    Date.today.should == Date.today
  end
end

If we use dynamic scope first, then if RSpec adds Spec::Date, it will suddenly break this spec. Lexical scope is more intuitive, and is expected by many normal uses today. On the other hand, we want to be able to access class variables in the eval'ed scope. I think a good solution is to add the dynamic scope _after_ the lexical scope, rather than _before_ it.

Yehuda Katz
Developer | Engine Yard
(ph) 718.877.1325


Shugo Maeda

lugemata,
17. nov 2009, 01:29:3317.11.09
kuni ruby...@ruby-lang.org
Hi,

At Tue, 17 Nov 2009 13:18:29 +0900,


Yehuda Katz <wyc...@gmail.com> wrote:
> I agree that we should have both, but I think that the lexical scope case
> should win. Consider the case of RSpec:
>
> describe "Date" do
> it "equals itself" do
> Date.today.should == Date.today
> end
> end
>
> If we use dynamic scope first, then if RSpec adds Spec::Date, it will
> suddenly break this spec. Lexical scope is more intuitive, and is expected
> by many normal uses today. On the other hand, we want to be able to access
> class variables in the eval'ed scope. I think a good solution is to add the
> dynamic scope _after_ the lexical scope, rather than _before_ it.

My patch first searches the constants of the receiver of class_eval, and
if it fails, then searches outer classes or modules. As a result, a
constant in the receiver may hide a constant in an outer class or
module.

My patch is useful if you know the receiver of class_eval, but you
don't know it, right?

Back to the example of MimeResponds:

module ActionController
module MimeResponds
extend ActiveSupport::Concern

included do
inheritable_accessor :responder, :mimes_for_respond_to,
:instance_writer => false

self.responder = Responder
clear_respond_to
end
end
end

class Foo
Responder = "this is not a responder which MimeResponds requires"

include ActionController::MimeResponds
end

The author of MimeResponds doesn't know that Foo defines Responder in
it, and it breaks the code (with my patch).

Did I catch your point?

If so, I agree that my patch is not useful in this situation.

However, I guess "to add the dynamic scope _after_ the lexical scope,
rather than _before_ it" doesn't affect class variable lookup, because
only the first element of Module.nesting is used during class variable
lookup.

I guess we have four options now:

(1) As you suggested, revert to the behavior of Ruby 1.8, and add a
new method (or flag) to enable the new behavior.
(2) Separate class variable lookup from constant lookup, and revert
constant lookup to the behavior of Ruby 1.8.
(3) Change nothing. You should always use the fully qualified form of
constant lookup.
(4) Apply my patch. You should still use the fully qualified form of
constant lookup, if you don't know the receiver of class_eval.

--
Shugo Maeda <sh...@ruby-lang.org>

Rick DeNatale

lugemata,
17. nov 2009, 23:10:1017.11.09
kuni ruby...@ruby-lang.org
On Tue, Nov 17, 2009 at 1:29 AM, Shugo Maeda <sh...@ruby-lang.org> wrote:

> However, I guess "to add the dynamic scope _after_ the lexical scope,
> rather than _before_ it" doesn't affect class variable lookup, because
> only the first element of Module.nesting is used during class variable
> lookup.

Maeda-san,

I'm intrigued by this thread, because I have a suspicion that it might
have something to do with a mystery I've been unable to understand
which seems to relate to the differences in 1.9 in either the eval
methods, class variable access, or both.

I've recently converted a Rails application to run on 1.9, and have a
strange phenomenon that if I am using Ruby 1.9 as my 'default' ruby
the rails generator scripts fail

$ which ruby
/Users/rick/.rvm/ruby-1.9.1-p243/bin/ruby
$ script/generate model foo
undefined method `exists' for #<ActiveSupport::BufferedLogger:0x00000102b3a250>

In order to run script/generate I need to switch to Ruby 1.8

This rails project makes use of the logbuddy gem
http://github.com/relevance/log_buddy

defines a module, whose init method is run when the gem is intialized:

module LogBuddy
# Configure and include LogBuddy into Object.
# You can pass in any of the following configuration options:
#
# * <tt>:logger</tt> - the logger instance that LogBuddy should use
(if not provided,
# tries to default to RAILS_DEFAULT_LOGGER, and then to a STDOUT logger).
# * <tt):log_to_stdout</tt> - whether LogBuddy should _also_ log to
STDOUT, very helpful for Autotest (default is +true+).
def self.init(options = {})
@logger = options[:logger]
@log_to_stdout = options.has_key?(:log_to_stdout) ?
options[:log_to_stdout] : true
mixin_to_object
end

# Add the LogBuddy::Mixin to Object instance and class level.
def self.mixin_to_object
Object.class_eval {
include LogBuddy::Mixin
extend LogBuddy::Mixin
}
end

class << self
include LogBuddy::Utils
def logger
return @logger if @logger
@logger = init_default_logger
end

def log_to_stdout?
@log_to_stdout
end

private

def init_default_logger
if Object.const_defined?("RAILS_DEFAULT_LOGGER")
@logger = Object.const_get("RAILS_DEFAULT_LOGGER")
else
require 'logger'
@logger = Logger.new(STDOUT)
end
end

end
end

and LogBuddy::Mixin looks (in part) like this:

module LogBuddy
module Mixin
def logger
LogBuddy.logger
end
end
end

Now the generate script is blowing up because Rails generators also
expect a method named logger and expect it to return a different kind
of logger.

That logger method is implemented as a cattr (another bit of
ActiveSupport 'metamagic'

module Rails
# Rails::Generator is a code generation platform tailored for the Rails
# web application framework.
module Generator
# The base code generator is bare-bones. It sets up the source and
# destination paths and tells the logger whether to keep its trap shut.
class Base
# ...
cattr_accessor :logger
end
end
end

and cattr_accessor calls both cattr_reader and cattr_writer,
cattr_reader generates class and instance methods

class Class
def cattr_reader(*syms)
syms.flatten.each do |sym|
next if sym.is_a?(Hash)
class_eval(<<-EOS, __FILE__, __LINE__)
unless defined? @@#{sym} # unless defined? @@hair_colors
@@#{sym} = nil # @@hair_colors = nil
end # end
#
def self.#{sym} # def self.hair_colors
@@#{sym} # @@hair_colors
end # end
#
def #{sym} # def hair_colors
@@#{sym} # @@hair_colors
end # end
EOS
end
end

def cattr_writer(*syms)
# code snipped for brevity.
end

def cattr_accessor(*syms)
cattr_reader(*syms)
cattr_writer(*syms)
end
end

In Ruby 1.8 things work as expected, in an instance of
Rails::Generator::Base or one of its subclasses, the logger method
produced by cattr_reader is found when the logger method is invoked.

But for some reason I haven't been able to decipher, in Ruby 1.9 the
logger method generated by the cattr_reader method isn't found, and
the Object#logger method defined by LogBuddy is executed instead.

I'd love any help in understanding what's going on here.

--
Rick DeNatale

Blog: http://talklikeaduck.denhaven2.com/
Twitter: http://twitter.com/RickDeNatale
WWR: http://www.workingwithrails.com/person/9021-rick-denatale
LinkedIn: http://www.linkedin.com/in/rickdenatale

Shugo Maeda

lugemata,
19. nov 2009, 01:38:2719.11.09
kuni ruby...@ruby-lang.org
Hi,

2009/11/17 Shugo Maeda <sh...@ruby-lang.org>:


> I guess we have four options now:
>
> (1) As you suggested, revert to the behavior of Ruby 1.8, and add a
>    new method (or flag) to enable the new behavior.

My proposal is as follows:

(1) Revert instance_eval, class_eval, and module_eval back to the
behavior of 1.8.
(2) But do not revert instance_exec, class_exec, and module_exec.

I have attached a patch.
My patch also reverts the behavior of class variables, but it may be
unnecessary.

--
Shugo Maeda

class_eval_1119.diff

Yehuda Katz

lugemata,
21. nov 2009, 15:02:5521.11.09
kuni ruby...@ruby-lang.org
Shugo,

I like this a lot. One final suggestion: instance_eval and class_eval should take arguments like instance_exec. Then, the only difference between instance_eval and instance_exec would be the constant lookup scope.

It also should not break any 1.8 code since instance_eval does not take arguments in 1.8.

I'm very excited about this!

Yehuda Katz
Developer | Engine Yard
(ph) 718.877.1325


Shugo Maeda

lugemata,
22. nov 2009, 11:41:2222.11.09
kuni ruby...@ruby-lang.org
Hi,

2009/11/22 Yehuda Katz <wyc...@gmail.com>:


> Shugo,
> I like this a lot. One final suggestion: instance_eval and class_eval should
> take arguments like instance_exec. Then, the only difference between
> instance_eval and instance_exec would be the constant lookup scope.
> It also should not break any 1.8 code since instance_eval does not take
> arguments in 1.8.

What do you think of this suggestion, Matz?

--
Shugo Maeda

Yukihiro Matsumoto

lugemata,
22. nov 2009, 18:49:3322.11.09
kuni ruby...@ruby-lang.org
Hi,

In message "Re: [ruby-core:26861] Re: Ruby constant lookup"


on Mon, 23 Nov 2009 01:41:22 +0900, Shugo Maeda <sh...@ruby-lang.org> writes:

|What do you think of this suggestion, Matz?

I am not sure I get the whole picture of this change and influence
from it. Let me discuss with you, when I get back home. OK?

matz.

Shugo Maeda

lugemata,
22. nov 2009, 19:01:3222.11.09
kuni ruby...@ruby-lang.org
Hi,

2009/11/23 Yukihiro Matsumoto <ma...@ruby-lang.org>:


> |What do you think of this suggestion, Matz?
>
> I am not sure I get the whole picture of this change and influence
> from it.  Let me discuss with you, when I get back home.  OK?

OK, have a nice trip.

--
Shugo Maeda

Shugo Maeda

lugemata,
22. nov 2009, 20:08:0822.11.09
kuni ruby...@ruby-lang.org
Hi,

2009/11/18 Rick DeNatale <rick.d...@gmail.com>:


> Maeda-san,
>
> I'm intrigued by this thread, because I have a suspicion that it might
> have something to do with a mystery I've been unable to understand
> which seems to relate to the differences in 1.9 in either the eval
> methods, class variable access, or both.

Does my patch fix the problem?

If not, it may be a different problem.
Would you create a minimal program which reproduces the problem?

--
Shugo Maeda

Rick DeNatale

lugemata,
23. nov 2009, 08:14:4123.11.09
kuni ruby...@ruby-lang.org
On Sun, Nov 22, 2009 at 8:08 PM, Shugo Maeda <sh...@ruby-lang.org> wrote:
> Hi,
>
> 2009/11/18 Rick DeNatale <rick.d...@gmail.com>:
>> Maeda-san,
>>
>> I'm intrigued by this thread, because I have a suspicion that it might
>> have something to do with a mystery I've been unable to understand
>> which seems to relate to the differences in 1.9 in either the eval
>> methods, class variable access, or both.
>
> Does my patch fix the problem?

I don't know. I haven't had a chance to try.


>
> If not, it may be a different problem.
> Would you create a minimal program which reproduces the problem?

I'll try. It's not the biggest problem on my list right now though.

Thanks for the attention.

Rick DeNatale

lugemata,
23. nov 2009, 08:35:4023.11.09
kuni ruby...@ruby-lang.org
On Mon, Nov 23, 2009 at 8:08 AM, Rick DeNatale <rick.d...@gmail.com> wrote:
> On Sun, Nov 22, 2009 at 8:08 PM, Shugo Maeda <sh...@ruby-lang.org> wrote:
>> Hi,
>>
>> 2009/11/18 Rick DeNatale <rick.d...@gmail.com>:
>>> Maeda-san,
>>>
>>> I'm intrigued by this thread, because I have a suspicion that it might
>>> have something to do with a mystery I've been unable to understand
>>> which seems to relate to the differences in 1.9 in either the eval
>>> methods, class variable access, or both.
>>
>> Does my patch fix the problem?
>
> I don't know.  I haven't had a chance to try.

Well I tried to apply the patch. It's been a while since I've built 1.9.

I did an svn update, applied the patch, then
autoconf
./configure
make

and get a syntax error in lex.c

clude/x86_64-darwin10.2.0 -I./include -I. -DRUBY_EXPORT
-D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -o parse.o -c parse.c
In file included from parse.y:6049:
lex.c:1: error: expected identifier or ‘(’ before ‘<<’ token

Your patch doesn't seem to touch this file. So i did
svn revert -R .
make clean
make

and got the same error.

→ svn log -l3
------------------------------------------------------------------------
r25889 | nobu | 2009-11-23 02:06:54 -0500 (Mon, 23 Nov 2009) | 4 lines

* thread_pthread.c (RUBY_STACK_MIN, RUBY_STACK_SPACE): delay for
platforms where PTHREAD_STACK_MIN is not compile time constant.
[ruby-dev:39751]

------------------------------------------------------------------------
r25888 | nobu | 2009-11-22 21:26:47 -0500 (Sun, 22 Nov 2009) | 2 lines

* dln.c (dln_find_1): removed duplication.

------------------------------------------------------------------------
r25887 | nobu | 2009-11-22 20:55:17 -0500 (Sun, 22 Nov 2009) | 2 lines

* dln.c (dln_find_1): fixed commit miss.

------------------------------------------------------------------------

Am I doing this with the right revision?

Shugo Maeda

lugemata,
23. nov 2009, 08:51:3323.11.09
kuni ruby...@ruby-lang.org
Hi,

2009/11/23 Rick DeNatale <rick.d...@gmail.com>:


> I did an svn update, applied the patch, then
>  autoconf
>  ./configure
> make
>
> and get a syntax error in lex.c
>
> clude/x86_64-darwin10.2.0 -I./include -I. -DRUBY_EXPORT
> -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE   -o parse.o -c parse.c
> In file included from parse.y:6049:
> lex.c:1: error: expected identifier or ‘(’ before ‘<<’ token
>
> Your patch doesn't seem to touch this file. So i did
> svn revert -R .
> make clean
> make
>
> and got the same error.

Can you try the following commands?

$ rm lex.c
$ make

If it fails, please show me your lex.c.

--
Shugo Maeda

Rick DeNatale

lugemata,
23. nov 2009, 10:18:4323.11.09
kuni ruby...@ruby-lang.org
patch -p1 <~/Downloads/class_eval_1119.diff
patching file compile.c
patching file eval.c
patching file insns.def
patching file node.h
patching file vm_core.h
patching file vm_eval.c
Hunk #2 succeeded at 1153 (offset 11 lines).
Hunk #3 succeeded at 1181 (offset 11 lines).
Hunk #4 succeeded at 1200 (offset 11 lines).
Hunk #5 succeeded at 1298 (offset 11 lines).
Hunk #6 succeeded at 1354 (offset 11 lines).
patching file vm_insnhelper.c

~/rubysource/ruby1.9 [svn:]
→ rm lex.c

~/rubysource/ruby1.9 [svn:]
→ make
gcc -O3 -ggdb -Wextra -Wno-unused-parameter -Wno-parentheses
-Wpointer-arith -Wwrite-strings -Wno-missing-field-initializers
-Wshorten-64-to-32 -Wno-long-long -pipe -I.
-I.ext/include/x86_64-darwin10.2.0 -I./include -I. -DRUBY_EXPORT
-D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -o main.o -c main.c
gcc -O3 -ggdb -Wextra -Wno-unused-parameter -Wno-parentheses
-Wpointer-arith -Wwrite-strings -Wno-missing-field-initializers
-Wshorten-64-to-32 -Wno-long-long -pipe -I.
-I.ext/include/x86_64-darwin10.2.0 -I./include -I. -DRUBY_EXPORT
-D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -o miniprelude.o -c miniprelude.c
gcc -O3 -ggdb -Wextra -Wno-unused-parameter -Wno-parentheses
-Wpointer-arith -Wwrite-strings -Wno-missing-field-initializers
-Wshorten-64-to-32 -Wno-long-long -pipe -I.
-I.ext/include/x86_64-darwin10.2.0 -I./include -I. -DRUBY_EXPORT
-D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -o class.o -c class.c
gcc -O3 -ggdb -Wextra -Wno-unused-parameter -Wno-parentheses
-Wpointer-arith -Wwrite-strings -Wno-missing-field-initializers
-Wshorten-64-to-32 -Wno-long-long -pipe -I.
-I.ext/include/x86_64-darwin10.2.0 -I./include -I. -DRUBY_EXPORT
-D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -o enum.o -c enum.c
gcc -O3 -ggdb -Wextra -Wno-unused-parameter -Wno-parentheses
-Wpointer-arith -Wwrite-strings -Wno-missing-field-initializers
-Wshorten-64-to-32 -Wno-long-long -pipe -I.
-I.ext/include/x86_64-darwin10.2.0 -I./include -I. -DRUBY_EXPORT
-D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -o error.o -c error.c
gcc -O3 -ggdb -Wextra -Wno-unused-parameter -Wno-parentheses
-Wpointer-arith -Wwrite-strings -Wno-missing-field-initializers
-Wshorten-64-to-32 -Wno-long-long -pipe -I.
-I.ext/include/x86_64-darwin10.2.0 -I./include -I. -DRUBY_EXPORT
-D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -o eval.o -c eval.c
gcc -O3 -ggdb -Wextra -Wno-unused-parameter -Wno-parentheses
-Wpointer-arith -Wwrite-strings -Wno-missing-field-initializers
-Wshorten-64-to-32 -Wno-long-long -pipe -I.
-I.ext/include/x86_64-darwin10.2.0 -I./include -I. -DRUBY_EXPORT
-D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -o load.o -c load.c
gcc -O3 -ggdb -Wextra -Wno-unused-parameter -Wno-parentheses
-Wpointer-arith -Wwrite-strings -Wno-missing-field-initializers
-Wshorten-64-to-32 -Wno-long-long -pipe -I.
-I.ext/include/x86_64-darwin10.2.0 -I./include -I. -DRUBY_EXPORT
-D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -o proc.o -c proc.c
gcc -O3 -ggdb -Wextra -Wno-unused-parameter -Wno-parentheses
-Wpointer-arith -Wwrite-strings -Wno-missing-field-initializers
-Wshorten-64-to-32 -Wno-long-long -pipe -I.
-I.ext/include/x86_64-darwin10.2.0 -I./include -I. -DRUBY_EXPORT
-D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -o gc.o -c gc.c
gc.c: In function ‘rb_node_newnode’:
gc.c:1105: warning: implicit conversion shortens 64-bit value into a
32-bit value
+ cp ./lex.c.blt lex.c
gcc -O3 -ggdb -Wextra -Wno-unused-parameter -Wno-parentheses
-Wpointer-arith -Wwrite-strings -Wno-missing-field-initializers
-Wshorten-64-to-32 -Wno-long-long -pipe -I.
-I.ext/include/x86_64-darwin10.2.0 -I./include -I. -DRUBY_EXPORT


-D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -o parse.o -c parse.c

parse.y:9840: error: redefinition of ‘rb_reserved_word’
keywords:82: error: previous definition of ‘rb_reserved_word’ was here
parse.y: In function ‘rb_reserved_word’:
parse.y:9841: warning: return makes pointer from integer without a cast
make: *** [parse.o] Error 1


Here's the lex.c (I just realized that this was generated by lex/flex

--

Rick DeNatale

lugemata,
23. nov 2009, 17:59:1023.11.09
kuni ruby...@ruby-lang.org
On Mon, Nov 23, 2009 at 10:18 AM, Rick DeNatale <rick.d...@gmail.com> wrote:

> Here's the lex.c


Oh oh, it looks like I forgot the link to lex.c

http://gist.github.com/241120

Shugo Maeda

lugemata,
23. nov 2009, 19:44:4023.11.09
kuni ruby...@ruby-lang.org
Hi,

2009/11/24 Rick DeNatale <rick.d...@gmail.com>:


>> Here's the lex.c
>
>
> Oh oh, it looks like I forgot the link to lex.c
>
> http://gist.github.com/241120

Your lex.c was copied from lex.c.blt, which looks old.
Please check out the latest source:

$ svn co http://svn.ruby-lang.org/repos/ruby/trunk ruby-trunk

--
Shugo Maeda

Shugo Maeda

lugemata,
24. nov 2009, 03:37:1524.11.09
kuni ruby...@ruby-lang.org
Hi,

2009/11/22 Yehuda Katz <wyc...@gmail.com>:


> I like this a lot. One final suggestion: instance_eval and class_eval should
> take arguments like instance_exec. Then, the only difference between
> instance_eval and instance_exec would be the constant lookup scope.
> It also should not break any 1.8 code since instance_eval does not take
> arguments in 1.8.

I talked with Yehuda on Skype, and confirmed his suggestion.

* If no arguments are passed to instance_eval or class_eval, it should
behave the same as 1.8.
* If any arguments are passed to instance_eval or class_eval, it
should yield them to a block.

This does not break any 1.8 code because instance_eval and class_eval
raise ArgumentError if both arguments and a block are given.

--
Shugo Maeda

Shugo Maeda

lugemata,
24. nov 2009, 09:47:1724.11.09
kuni ruby...@ruby-lang.org
Hi,

2009/11/24 Shugo Maeda <sh...@ruby-lang.org>:


> * If no arguments are passed to instance_eval or class_eval, it should
> behave the same as 1.8.

instance_eval does not yield the receiver in Ruby 1.9.
This change is introduced as a result of the following discussion:

http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/7365

Should instance_eval yield the receiver or not?

--
Shugo Maeda

Rick DeNatale

lugemata,
24. nov 2009, 11:46:2724.11.09
kuni ruby...@ruby-lang.org

If this were a democracy <G>, I'd vote to make it work as it does in
1.8 and yield the receiver.

Shugo Maeda

lugemata,
1. dets 2009, 00:44:2701.12.09
kuni ruby...@ruby-lang.org
Hi,

2009/11/23 Yukihiro Matsumoto <ma...@ruby-lang.org>:


> |What do you think of this suggestion, Matz?
>
> I am not sure I get the whole picture of this change and influence
> from it.  Let me discuss with you, when I get back home.  OK?

I have discussed the issue with Matz.

He has rejected my proposal because it's not coherent.
# Strictly speaking, he said "suji ga warui",
# but I can't translate it into English:(

Instead, he would like to revert all of instance_eval, instance_exec,
class_eval, and class_exec to the behavior of 1.8 (including class
variables). It also means that instance_eval does not passes its
arguments to given blocks. If it does, instance_exec gets
unnecessary.

I agree with him, but any objections?

--
Shugo Maeda

Shugo Maeda

lugemata,
3. dets 2009, 13:34:1103.12.09
kuni ruby...@ruby-lang.org
Hi,

2009/12/1 Shugo Maeda <sh...@ruby-lang.org>:


> Instead, he would like to revert all of instance_eval, instance_exec,
> class_eval, and class_exec to the behavior of 1.8 (including class
> variables).  It also means that instance_eval does not passes its
> arguments to given blocks.  If it does, instance_exec gets
> unnecessary.
>
> I agree with him, but any objections?

I have just commited it to the SVN trunk.

--
Shugo Maeda

Vasta kõigile
Vasta autorile
Saada edasi
0 uut sõnumit