From: Shadowfirebird Date: 2008-07-24T00:21:24+09:00 Subject: Re: circular 'require' Yes, I can see now that in your example no order of loading will allow the objects to be defined before they are used. That is certainly a trap to avoid. Thanks, Michael. The annoying thing is that my actual code worked "fine" when it was all in one file but stopped working when I split the objects into different files. And of course, it's too long to post here. I may come back and ask different questions once I've had a bit of a think. Thanks to everyone. Shadowfirebird. On Wed, Jul 23, 2008 at 3:39 PM, Michael T. Richter wrote: > On Wed, 2008-07-23 at 22:48 +0900, Shadowfirebird wrote: > >> I found a very easy way around it. This is what bothers me. If it's >> that easy, why doesn't require do it? > > > > Try my code with that: > > > michael@isolde:~/junk$ cat test1.rb > $" << "test1.rb" > load("test2.rb") unless $".include?("test2.rb") > class NeededInTest2 > @@funny_stuff = NeededInTest1.new > end > > michael@isolde:~/junk$ cat test2.rb > $" << "test2.rb" > load("test1.rb") unless $".include?("test1.rb") > class NeededInTest1 > @@funny_stuff = NeededInTest2.new > end > > michael@isolde:~/junk$ ruby test1.rb > ./test2.rb:4: uninitialized constant NeededInTest1::NeededInTest2 (NameError) > from test1.rb:2:in `load' > from test1.rb:2 > > > The real solution remains a proper system of modules in Ruby. > > >> # test1.rb >> $" << "test1.rb" >> load("test2.rb") unless $".include?("test2.rb") >> class One < Two >> def self.testone(); Two.whoistwo; end >> def self.whoisone(); puts "class one"; end >> end >> >> # test2.rb >> $" << "test2.rb" >> load("test1.rb") unless $".include?("test1.rb") >> class Two >> def self.testtwo(); One.whoisone; end >> def self.whoistwo(); puts "class two"; end >> end >> >> >> On Wed, Jul 23, 2008 at 2:03 PM, Michael T. Richter >> wrote: >> > On Wed, 2008-07-23 at 20:39 +0900, Calamitas wrote: >> > >> >> test1.rb is executed twice, but what probably caused the error in the >> >> OP's original program (the OP pared it down to a point where it >> >> actually did "work") is the fact that "the rest of test1.rb" is >> >> executed before "the rest of test2.rb". It can probably be solved by >> >> doing "ruby -r test1.rb" instead, but that's icky. Generally, if I >> >> *were* to use circular requires, I'd never put "executable code" in >> >> either file, just "declarations". I don't use them though. Not anymore >> >> after I've been bitten a few times. >> > >> > >> > Here's what the OP was talking about, I suspect, taken down to its >> > briefest possible example: >> > >> > >> > $ cat test1.rb >> > require 'test2' >> > class NeededInTest2 >> > @@funny_stuff = NeededInTest1.new >> > end >> > >> > michael@isolde:~/junk$ cat test2.rb >> > require 'test1' >> > class NeededInTest1 >> > @@funny_stuff = NeededInTest2.new >> > end >> > >> > michael@isolde:~/junk$ ruby test1.rb >> > ./test1.rb:3: uninitialized constant NeededInTest2::NeededInTest1 (NameError) >> > from /home/michael/software/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in `gem_original_require' >> > from /home/michael/software/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in `require' >> > from ./test2.rb:1 >> > from /home/michael/software/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in `gem_original_require' >> > from /home/michael/software/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in `require' >> > from test1.rb:1 >> > >> > >> > This is the problem boiled down to its essence. There is no easy way >> > out of this either that doesn't either a) mangle the architecture or b) >> > fail. You can't use something like C/++'s "include guards" to get >> > around this, nor can you use any kind of super-class elevation trick or >> > the like. What would be needed to solve this issue would be for ruby to >> > have a proper sense of modules and do linkage across those instead of >> > treating the entire tree of requires as, in effect, one ginormous text >> > file. >> > >> > -- >> > Michael T. Richter (GoogleTalk: >> > ttmrichter@gmail.com) >> > Theory is knowledge that doesn't work. Practice is when everything works >> > and you don't know why. (Hermann Hesse) >> > >> >> >> > > -- > Michael T. Richter (GoogleTalk: > ttmrichter@gmail.com) > It's OK to figure out murder mysteries, but you shouldn't need to figure > out code. You should be able to read it. (Steve McConnell) > -- Me, I imagine places that I have never seen / The colored lights in fountains, blue and green / And I imagine places that I will never go / Behind these clouds that hang here dark and low But it's there when I'm holding you / There when I'm sleeping too / There when there's nothing left of me / Hanging out behind the burned-out factories / Out of reach but leading me / Into the beautiful sea