How can I extend the ruby ​​class from the class defined in the module?

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 / material / baz.rb

 module Foo module Stuff class Baz < Bar end end end 

I get the following error:

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

Am I doing something wrong here? Is this possible in Ruby? In case that matters, I only do this because I need to inherit the initialize method.

+6
source share
4 answers

It works great 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 this should be a problem with the way or order in which you need your files.

In addition, if you need only one specific method from Foo::Bar to Foo::Stuff::Baz , you can put this method into a module and include this module in both classes.

+3
source

Your foo/stuff/baz.rb does not contain a require statement, and you will not tell anything about the main program. Therefore, I think that you just do not download the code.

Ruby does not have automatic downloads depending on the path to the folder; you must explicitly download the source code. In your case, you will need 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 

Result:

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

The initialization method Foo::Bar executed.


A more realistic architecture would be to use a main file in which you load all the code files, for example:

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

and foo.rb will contain:

 require_relative 'foo/bar' require_relative 'foo/stuff/baz' 
+3
source

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

+1
source

This does not work because there is no reference to the Bar class in the baz.rb namespace; should just type:

 class Bar; end 

So the baz.rb structure will just have: (foo / stuff / baz.rb)

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

Source: https://habr.com/ru/post/1013810/


All Articles