[英]How can I extend a ruby class from a class defined in a module?
I have the following files: 我有以下文件:
file.rb
file.rb
require_relative 'foo/bar'
baz = Foo::Stuff::Baz.new
# do stuff
foo/bar.rb
富/ bar.rb
require_relative 'stuff/baz'
module Foo
class Bar
def initialize
# do stuff
end
end
end
foo/stuff/baz.rb
富/材料/ baz.rb
module Foo
module Stuff
class Baz < Bar
end
end
end
I get the following error: 我收到以下错误:
`': uninitialized constant Foo::Stuff::Bar (NameError)
`':未初始化的常量Foo :: Stuff :: Bar(NameError)
Is there something I'm doing wrong here? 我有什么问题吗? Is this even possible in Ruby?
这在Ruby中是否可行? In case it matters, I'm only doing this because I need to inherit the initialize method specifically.
如果它很重要,我只是这样做,因为我需要专门继承initialize方法。
Your foo/stuff/baz.rb
does not contain any require
statement and you tell nothing about a main programm. 你的
foo/stuff/baz.rb
不包含任何require
语句,你对主程序没有任何说明。 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. Ruby没有自动加载,具体取决于文件夹路径,您必须显式加载源代码。 In your case you need a
require_relative '../bar'
in the file foo/stuff/baz.rb
. 在你的情况下,你需要文件
foo/stuff/baz.rb
的require_relative '../bar'
。 Then the class Foo::Bar
is known: 然后知道类
Foo::Bar
:
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. 执行
Foo::Bar
的initialize方法。
A more realistic architecture would be the usage of a main file where you load all code files, eg: 更现实的架构是使用加载所有代码文件的主文件,例如:
foo.rb
foo/bar.rb
foo/stuff/baz.rb
and foo.rb would contain: 和foo.rb将包含:
require_relative 'foo/bar'
require_relative 'foo/stuff/baz'
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. 另外,如果你只需要
Foo::Stuff::Baz
Foo::Bar
一个特定方法,你可以把这个方法放在一个模块中,并在这两个类中包含这个模块。
Foo::Bar
is defined. Foo::Bar
已定义。 You can also access ::Foo::Bar
("root" module) when there are issues finding the right namespace. 当找到正确的命名空间时,您还可以访问
::Foo::Bar
(“root”模块)。
It does not work because in baz.rb namespace there is no any reference to the Bar class; 它不起作用,因为在baz.rb命名空间中没有任何对Bar类的引用; should simply enter:
应该简单地输入:
class Bar; end
So the baz.rb structure becomes simply have: (foo/stuff/baz.rb) 所以baz.rb结构变得简单了:(foo / stuff / baz.rb)
module Foo
class Bar; end
module Stuff
class Baz < Bar
end
end
end
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.