简体   繁体   中英

How can I get a class and submodule to interact with the same module property?

I have the following files:

lib/b/c/d.rb

module B
  module C
    class D
      def initialize
        puts "#{@msg}"
      end
    end
  end
end

a.rb

class A
  include B
  def initialize
    @msg = 'Hello world'
    B::C::D.new
  end
end

I would like the following command to output "Hello world" .

A.new

Instead, it just prints an empty string. What am I doing wrong?

I plugged stuff into IRB, and notice what happens when you do this, instead:

a.rb

class A
  include B
  attr_accessor :d
  def initialize
    @msg = 'Hello world'
    d = B::C::D.new
  end
end

If I then, in IRB:

> a= A.new
 => #<A:0x007f87149e1658 @msg="Hello world", @d=#<B::C::D:0x007f87149e1608>> 
> a.d
 => #<B::C::D:0x007f87149e1608>

So what appears to be going on is that you're not mixing in class D , you're making a local instance of class D within the initializer for A .

This seems more like what you might want:

class A < B::C::D
  include B
  attr_accessor :d
  def initialize
    @msg = 'Hello world'
    super
  end
end

If you don't want to inherit from D, see this answer: Why is the module initialize method not called?

I've simplified the problem significantly in the question, but I found what I was looking for. mattr_accessor let me define attributes on a module basis, instead of on an instance basis after including it as a mixin.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM