From: "David A. Black" Date: 2009-10-02T22:03:19+09:00 Subject: [ruby-core:25901] Re: struggling to convince myself 1.9's constant lookup rules make any sense This message is in MIME format. The first part should be readable text, while the remaining parts are likely unreadable without MIME-aware tools. --1926193751-1562178717-1254488585=:13206 Content-Type: TEXT/PLAIN; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 8BIT Hi -- On Fri, 2 Oct 2009, ara.t.howard wrote: > > > On Oct 1, 8:47�am, "David A. Black" wrote: >> Hi -- >> >> >> >> >> First thought: because the purpose of the rule, I think, is to clarify >> that there's a distinction, and the cost of that clarification is that >> it's a mistake not to make the distinction. >> >> For example: >> >> class C >> � �def self.run(&block) >> � � �class_eval(&block) >> � �end >> end >> >> class D >> � �MyConst = 1 >> � �C.run { p MyConst } >> end >> >> That code will give you "unknown constant C::MyConst" in 1.9. The >> reasoning, as I understand it, is that the caller cannot depend one >> way or the other on whether there's a constant called MyConst in the >> evaluating class. In other words, there could be: >> >> � �class C >> � � �MyConst = 2 >> >> etc., in which case the call from D would not use D::MyConst -- so >> since D has no jurisdiction over whether C::MyConst exists, the only >> consistent approach is to assume that C will *always* have the >> responsibility for resolving MyConst. >> > > > hrm. i don't really see it that way, at least it seems directly > opposed to how this runs, which prints '1' in both 1.8 and 1.9 > > cfp:~ > cat a.rb > class C > def C.run(&block) class_eval(&block) end > def C.myConst() 2 end > end > > class D > myConst = 1 > C.run { p myConst } > end > > cfp:~ > ruby18 a.rb > 1 > > cfp:~ > ruby19 a.rb > 1 > > > here the rule is *clearly* that the closure's scope comes before the > caller's scope. but not that it is *not* an exclusive scope - a > failure to to a lookup on the closure the falls to the caller: > > cfp:~ > cat a.rb > class C > def C.run(&block) class_eval(&block) end > def C.myConst() 2 end > end > > class D > C.run { p myConst } > end > > cfp:~ > ruby18 a.rb > 2 > > cfp:~ > ruby19 a.rb > 2 Right -- it's different for local variables, but constant visibility and local variable scope have never been in lockstep. class C x = 1 X = 1 module M p X # 1 p x # error end end so I'm open to the possibility that they won't behave the same in the face of closures. It's possible that I'm just going with the flow too much, but since constants have never been the same as locals, I guess I tend to accept that their visibility rules will be somewhat sui generis and not necessarily patterned after anything else. I suspect that if it had been the 1.9 way in 1.8 and then changed to the 1.8 way in 1.9, I'd go with that flow too. Anyway, it's an interesting catch, and I'm curious to hear from any Japanese Mormon language designers who might have some thoughts on it :-) David -- David A. Black, Director Ruby Power and Light, LLC (http://www.rubypal.com) Ruby/Rails training, consulting, mentoring, code review Book: The Well-Grounded Rubyist (http://www.manning.com/black2) --1926193751-1562178717-1254488585=:13206--