如何从模块中定义的类扩展ruby类?

时间:2017-01-05 22:41:11

标签: ruby

我有以下文件:

  

file.rb

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

富/ bar.rb

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

富/东西/ baz.rb

module Foo
    module Stuff
        class Baz < Bar
        end
    end
end

我收到以下错误:

  

`&#39 ;:未初始化的常量Foo :: Stuff :: Bar(NameError)

我在这里做错了吗?这在Ruby中是否可行?如果它很重要,我只是这样做,因为我需要专门继承initialize方法。

4 个答案:

答案 0 :(得分:3)

您的foo/stuff/baz.rb不包含任何require声明,而您对主程序一无所知。所以我认为你只是不加载代码。

Ruby根据文件夹路径没有自动加载,您必须显式加载源代码。在您的情况下,文件require_relative '../bar'中需要foo/stuff/baz.rb。然后知道班级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

结果:

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

执行Foo::Bar的initialize-method。

更现实的架构是使用加载所有代码文件的主文件,例如:

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

和foo.rb将包含:

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

答案 1 :(得分:3)

将它们放在同一个脚本中时效果很好:

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]

因此,您需要文件的方式或顺序一定存在问题。

此外,如果您只需要Foo::BarFoo::Stuff::Baz中的一个特定方法,则可以将此方法放在模块中,并将此模块包含在这两个类中。

答案 2 :(得分:1)

Foo::Bar已定义。当找到正确的命名空间时,您还可以访问::Foo::Bar(&#34; root&#34;模块)。

答案 3 :(得分:0)

它不起作用,因为在baz.rb命名空间中没有任何对Bar类的引用;应该简单地输入:

class Bar; end

所以baz.rb结构变得简单:(foo / stuff / baz.rb)

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