From: Robert Klemme Date: 2009-12-30T18:34:16+09:00 Subject: Re: Using #include at the instance level? --0016e6d77e322d0f67047beed76b Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable 2009/12/30 fkocherga : >> >> AFAIK it hasn't changed and your code could never work in any version >> of Ruby because the const lookup in method #n is done _statically_. > > But it should not, consider: > > module M > =A0module N > =A0end > end > > #Class.new do <---- This does not work in 1.8.7! > class B < Object > =A0include M > =A0N > end > > When 'class B < Object' replaced with 'Class.new do' the Ruby 1.8.7 inter= preter complains about uninitialized constant N. What is the big reason for= dynamically defined class to behave so differently? It would be very non o= bvious and unexpected behavior. Actually both cases work as expected in Rub= y 1.9.1 and this is correct behavior according to the Ruby Draft. Thanks for the test case! It never occurred to me to do a const lookup in a class defined with a class body so I never stumbled across this. I did a bit of research and this is what I found: Statement from Matz about the change: "In 1.8, constant uses lexical look-up, even within the block given to instance_eval(). We changed this behavior in 1.9 to simplify things." http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/181646 Found via http://eigenclass.org/hiki/withdrawn-experimental-ruby-features - I am not so sure about the "experimental" status of this though - maybe this is due to the last update date of the page in 2007... Adam Gardner also made an interesting observation about the difference between const_get and direct constant lookup: http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/333677 (I have changed the test output to easier interpret it. See attachment.) There's also this discussion http://blade.nagaokaut.ac.jp/cgi-bin/vframe.rb/ruby/ruby-core/25865?25832-2= 6487 And this http://blade.nagaokaut.ac.jp/cgi-bin/vframe.rb/ruby/ruby-talk/334016?333995= -335445 To sum it up: Ruby 1.9 changed lookup rules from lexical (aka static) to dynamic. IMHO this explains the observed different behavior. Thanks again for poking. Kind regards robert --=20 remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/ --0016e6d77e322d0f67047beed76b Content-Type: application/octet-stream; name="const-lookup-2.rb" Content-Disposition: attachment; filename="const-lookup-2.rb" Content-Transfer-Encoding: base64 X-Attachment-Id: f_g3twgwmm0 ZGVmIHByKG1zZykKICBsaW5lID0gY2FsbGVyLmZpcnN0Wy86KFxkKykoPzo6aW4pPy8sIDFdLnRv X2kKICBwcmludGYgIiU0ZCAlc1xuIiwgbGluZSwgbXNnCmVuZAoKbW9kdWxlIFoKICBjbGFzcyBB CiAgICBkZWYgaW5pdGlhbGl6ZQogICAgICBwciAiWjo6QSIKICAgIGVuZAogIGVuZAogIG1vZHVs ZSBZCiAgICBtb2R1bGUgWAogICAgICBjbGFzcyBBCiAgICAgICAgZGVmIGluaXRpYWxpemUKICAg ICAgICAgIHByICJaOjpZOjpYOjpBIgogICAgICAgIGVuZAogICAgICBlbmQKICAgIGVuZAogICAg Y2xhc3MgQgogICAgICBpbmNsdWRlIFgKICAgICAgZGVmIGluaXRpYWxpemUKICAgICAgICBwciAi Wjo6WTo6QiIKICAgICAgICBAYSA9IEEubmV3CiAgICAgIGVuZAogICAgZW5kCiAgZW5kCmVuZAoK Wjo6QS5uZXcKIyA9PiAjPFo6OkE6MHg1NzNkYz4KClo6Olk6Olg6OkEubmV3CiMgPT4gIzxaOjpZ OjpYOjpBOjB4NTAzMGM+CgpaOjpZOjpCLm5ldwojID0+ICM8Wjo6WTo6QjoweDQ4ZTE4IEBhPSM8 Wjo6QToweDQ4ZGM4Pj4KCnByIFo6Olk6OkIuY29uc3RfZ2V0KCJBIikKIyA9PiBaOjpZOjpYOjpB Cgptb2R1bGUgWgogIG1vZHVsZSBZCiAgICBjbGFzcyBCCiAgICAgIHByIGNvbnN0X2dldCgiQSIp CiAgICBlbmQKICBlbmQKZW5kCiMgPT4gWjo6WTo6WDo6QQoKbW9kdWxlIFoKICBtb2R1bGUgWQog ICAgY2xhc3MgQgogICAgICBwciBBCiAgICBlbmQKICBlbmQKZW5kCiMgPT4gWjo6QQo= --0016e6d77e322d0f67047beed76b--