6

I have the following files:

file.rb

require_relative 'foo/bar'
baz = Foo::Stuff::Baz.new
# do stuff

foo/bar.rb

require_relative 'stuff/baz'
module Foo
    class Bar
        def initialize
            # do stuff
        end
    end
end

foo/stuff/baz.rb

module Foo
    module Stuff
        class Baz < Bar
        end
    end
end

I get the following error:

`': uninitialized constant Foo::Stuff::Bar (NameError)

Is there something I'm doing wrong here? Is this even possible in Ruby? In case it matters, I'm only doing this because I need to inherit the initialize method specifically.

4 Answers 4

3

It works just fine when you put them in the same script :

module Foo
  class Bar
    def initialize
      # do stuff
    end
  end
end

module Foo
  module Stuff
    class Baz < Bar
    end
  end
end

p Foo::Stuff::Baz.ancestors
#=> [Foo::Stuff::Baz, Foo::Bar, Object, Kernel, BasicObject]

So it must be a problem with the way or order in which you require your files.

Also, if you just need just one specific method from Foo::Bar in Foo::Stuff::Baz, you could put this method in a module, and include this module in both classes.

Sign up to request clarification or add additional context in comments.

1 Comment

Yep, you were right. The problem was that I require foo/stuff/baz.rb in foo/bar.rb. I'm marking your answer as the correct one.
3

Your foo/stuff/baz.rb does not contain any require statement and you tell nothing about a main programm. So I think you just don't load the code.

Ruby has no automatic loading depending on folder path, you must explicitly load the source code. In your case you need a require_relative '../bar' in the file foo/stuff/baz.rb. Then the class Foo::Bar is known:

require_relative '../bar'

module Foo
    module Stuff
        class Baz < Bar
        end
    end
  end

  p Foo::Stuff::Baz.new
  p Foo::Stuff::Baz.ancestors

The result:

#<Foo::Stuff::Baz:0x00000002ff3c30>
[Foo::Stuff::Baz, Foo::Bar, Object, Kernel, BasicObject]

The initialize-method of Foo::Bar is executed.


A more realistic architecture would be the usage of a main file where you load all code files, e.g.:

foo.rb
foo/bar.rb
foo/stuff/baz.rb

and foo.rb would contain:

require_relative 'foo/bar'
require_relative 'foo/stuff/baz'

3 Comments

I do have the require_relative statements in there, actually. I should have included them in my post.
So, if I'm not mistaken, I should have the require_relatives for everything in the main file. I'll give that a shot instead.
Thanks, I figured it out. I realized that the problem is the require statement in my foo/bar.rb file.
1

Foo::Bar is defined. You can also access ::Foo::Bar ("root" module) when there are issues finding the right namespace.

Comments

0

It does not work because in baz.rb namespace there is no any reference to the Bar class; should simply enter:

class Bar; end

So the baz.rb structure becomes simply have: (foo/stuff/baz.rb)

module Foo
  class Bar; end
  module Stuff
    class Baz < Bar
    end
  end
end

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.