指定 class with forwardable

Specify class with forwardable

我正在尝试使用 ruby 的 forwardable module 使一个 class 中的一些变量可供另一个 class 访问。但是,我在执行此操作时遇到了一些麻烦。

似乎我能够 'forward' self(代码的第一位)中的一些变量,但我无法转发 class 中的一些变量(第二位代码)

以下作品:

require 'forwardable'
module ModuleName
  #
  class << self
    attr_accessor :config
    def run
      @config = {hey: 'hi', jay: 'ji'}
      puts "1) Config = #{config}"
    end
  end

  #
  class Start
    extend Forwardable
    def_delegators ModuleName, :config
    def run
      puts "2) Config = #{config}"
    end
  end
end


ModuleName.run
(ModuleName::Start.new).run

#=> 1) Config = {:hey=>"hi", :jay=>"ji"}
#=> 2) Config = {:hey=>"hi", :jay=>"ji"}

但这不是

require 'forwardable'
module ModuleName
  #
  class Data
    attr_accessor :config
    def run
      @config = {hey: 'hi', jay: 'ji'}
      puts "1) Config = #{config}"
    end
  end

  #
  class Start
    extend Forwardable
    def_delegators ModuleName::Data, :config
    def run
      puts "2) Config = #{config}"
    end
  end
end


(ModuleName::Data.new).run
(ModuleName::Start.new).run

#=> 1) Config = {:hey=>"hi", :jay=>"ji"}
#=> /Users/ismailm/Desktop/ex.rb:17:in `run': undefined method `config' for ModuleName::Data:Class (NoMethodError)

你能帮忙修复这部分代码吗...

通常,当您在两个 class 对象之间进行委托时,一个对象包含另一个对象的 实例 。你打电话给 (ModuleName::Data.new).run 的事实对我来说意味着这就是你想要做的,但不知何故错过了这样一个事实,即你需要将所包含的 class 的实例存储在某个地方以便接收致电 :config

你的第二段代码的这种变体更接近我期望在委托场景中看到的:

require 'forwardable'
module ModuleName
  #
  class Data
    attr_accessor :config

    def initialize
      @config = {hey: 'hi', jay: 'ji'}
    end

    def run
      puts "1) Config = #{config}"
    end
  end

  #
  class Start
    extend Forwardable

    def initialize data_obj = Data.new()
      @data = data_obj
    end

    def_delegators :@data, :config

    def run
      puts "2) Config = #{config}"
    end
  end
end


(ModuleName::Data.new).run
(ModuleName::Start.new).run

我将构造函数更改为 ModuleName::Start 以显示通用模式,此处未使用。也就是说,您经常传入包装对象,或者更常见的是允许您构造一个新对象并将其分配给您希望委托给的实例变量的参数。

一个小的相关更改:在您的原始代码中,@config 的值仅通过调用 :run 设置,因此直接委托给 :config 不会读取您的值期待在测试中。它在第一个版本中有效,因为 @config 是在第一次调用模块上的 run 时设置的,然后在第二次委托调用时作为单例方法全局读取。我已经通过在 Data 的构造函数中设置它来解决这个问题,但是当然任何在您委托的实例上设置 @config 值的东西都可以工作。