George O. wrote:
Michael J. [email protected] writes:
class B < A
# Do nothing
Where’s the brutally obvious mistake I made? Why would A be an
Because it hasn’t been defined when “class B < A” is evaluated.
Here’s what happens, step by step:
- irb evaluates: require “a”
- ruby parses the ‘a.rb’ file into an internal representation, doing
syntax checking along the way
- ruby evaluates the first expression: require “b”
- ruby parses the ‘b.rb’ file into an internal representation,
doing syntax checking along the way
- ruby evaluates the first expression: require “a”. As ‘a.rb’ has
already been required, this does effectively nothing (see `ri
- ruby evaluates the next expression: class B < A … end. As A
is not defined, ruby raises the exception you see.
Why does ‘a.rb’ require ‘b.rb’ ? Circular requires are a bad thing.
You’ll need to break it up.
One option is to just have the toplevel file just have a whole
sequence of requires, and have each source file define what it needs
to without messing around with any requires whatsoever.
Hope this helps.
Thanks for your help, George. That’s really interesting how the ruby
If instead I did, require “b” in irb, it would have worked because the
following sequence would have happened:
- Parse b.rb until hitting the line: require “a”
- Parse a.rb (in the process, learning about class A)
- Continue parsing b.rb
- Class B’s definition (subclassed to A) now makes sense to the parser
and everything works.
Crazy stuff. It makes me want to write a programming language.
In the end, after reading your post, I decided to move class B into the
bottom of a.rb and my unit tests passed. It just seemed simpler than
creating a file that just requires all the different class files.
(Thanks again for taking the time to explain how the parser worked)