我正在尝试使用ruby的forwardable
module来使一个类中的某些变量可以被另一个类访问。但是我在做这件事时遇到了一些麻烦。
似乎我能够'转发'self
中的一些变量(代码的第一位),但是我无法在类中转发某些变量(第二位代码)
以下作品:
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)
你能帮忙解决这部分代码......
答案 0 :(得分:2)
通常,当您在两个类之间委派时,一个对象包含另一个对象的实例。你调用(ModuleName::Data.new).run
这个事实对我意味着你正在尝试做的事情,但是在某种程度上错过了你需要将某个包含的类的实例存储在某个地方以便接收对{{{ 1}}
您的第二段代码的这种变化更接近我在委托方案中看到的内容:
: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
值的东西都可以工作。