Unable to include a Class in to another class in Ruby: uninitialized constant (NameError)
Lets say I have three classs, each define in its own file. e.g. ClassA in ClassA.rb etc...
class ClassA
def initialize
end
def printClassA
puts "This is class A"
end
end
class ClassB
def initialize
end
def printClassB
puts "This is class B"
end
end
class ClassC
def initialize
end
def bothClasses
a = ClassA.new
b = ClassB.new
a.printClassA
b.printClassB
end
end
As you can see, ClassC needs the other two classes in order to function correctly. I as开发者_如何学运维sume, there needs to be a way to import/include/load the other two classes in ClassC.
I'm new to Ruby and I've tried every permutation of load/include/require and I cannot figure out how to get this to run.
I normally just get:
classc.rb:2:in `<class:ClassC>': uninitialized constant ClassC::ClassA (NameError)
from classc.rb:1:in `<main>'
Or a syntax error with my import/include/require statements.
Using Windows 7, Ruby 1.9.2, RadRails, all files are in the same project and source folder.
I'm sorry if this question is similar to some of the other questions on here, but most of the answers to resolving the "uninitialized constant" is to "just require the file". I've tried and it isn't working.
I think your problem is that $:
, the variable that controls where require
looks for files, no longer includes the current directory in Ruby 1.9.2 and higher (for security reasons). To tell Ruby where to look for the file, you need to do one of:
require_relative 'ClassA' # which looks in the same directory as the file where the method is called
# or #
require './ClassA' # which looks in the current working directory
If I keep everything in one file, and add two lines to your code it works fine on 1.9.2:
class ClassA
def initialize
end
def printClassA
puts "This is class A"
end
end
class ClassB
def initialize
end
def printClassB
puts "This is class B"
end
end
class ClassC
def initialize
end
def bothClasses
a = ClassA.new
b = ClassB.new
a.printClassA
b.printClassB
end
end
c = ClassC.new
c.bothClasses
# >> This is class A
# >> This is class B
That tells me the code is fine, the problem is in your inclusion of the files.
I split out the first two classes into separate files, "classa.rb" and "classb.rb" respectively, then modified the file to:
require_relative './classa'
require_relative './classb'
class ClassC
def initialize
end
def bothClasses
a = ClassA.new
b = ClassB.new
a.printClassA
b.printClassB
end
end
c = ClassC.new
c.bothClasses
After running it I got the same results showing it ran correctly.
I use './path/to/file' because it's self-documenting where I'm looking, but 'path/to/file', or, in this case 'classa' would work as well.
Then, I switched to Ruby 1.8.7, and changed the require_relative
lines to require
, and saved out the file again. Running it from the command-line worked correctly again:
require './classa'
require './classb'
class ClassC
def initialize
end
def bothClasses
a = ClassA.new
b = ClassB.new
a.printClassA
b.printClassB
end
end
c = ClassC.new
c.bothClasses
For security reasons, Ruby 1.9+ removed the current directory '.' from the list of directories searched by require
. Because they knew we'd hunt them down with pitchforks and torches, they added the require_relative
command, which allows searching in the current directory and below.
精彩评论