Ruby 使用块配置类

Ruby 使用块配置类,ruby,Ruby,我有一个基本模块,其中包含一些逻辑,它包含在各种类中。现在我需要一个configure块来设置类的行为方式 我尝试了以下代码: class MyConfig attr_accessor :foo, :bar end module BaseModule def self.included base base.include InstanceMethods base.extend ClassMethods end module ClassMethods a

我有一个基本模块,其中包含一些逻辑,它包含在各种类中。现在我需要一个
configure
块来设置类的行为方式

我尝试了以下代码:

class MyConfig
  attr_accessor :foo, :bar
end

module BaseModule
  def self.included base
    base.include InstanceMethods
    base.extend ClassMethods
  end

  module ClassMethods
    attr_reader :config

    def configure &block
      @config = MyConfig.new
      block.call(@config)
    end
  end

  module InstanceMethods
    def do_something
      puts self.class.config.inspect
    end
  end
end

class MyClass1
  include BaseModule

  configure do |config|
    config.foo = "foo"
  end
end

class MyClass2
  include BaseModule

  configure do |config|
    config.bar = "bar"
  end
end

MyClass1.new.do_something
#<MyConfig:0x007fa052877ea0 @foo="foo">
MyClass2.new.do_something
#<MyConfig:0x007fa052877ce8 @bar="bar">
class MyConfig
属性存取器:foo,:bar
结束
模块基模块
def自含式底座
base.include InstanceMethods
base.extend类方法
结束
模块类方法
属性读取器:配置
def配置和阻止
@config=MyConfig.new
block.call(@config)
结束
结束
模块实例方法
做点什么
将self.class.config.inspect
结束
结束
结束
类别MyClass1
包含基本模块
配置do | config|
config.foo=“foo”
结束
结束
类别MyClass2
包含基本模块
配置do | config|
config.bar=“bar”
结束
结束
MyClass1.new.做点什么
#
MyClass2.new.do\u做点什么
#
  • 我不确定模块/类的实例变量
    @config
    是否是配置类的最佳方式。这是正确的方法,还是有更好的解决方案
  • 当模块仅包含在
    include BaseModule
    中时,是否也可以使用
    base.extend ClassMethods
    ?开发人员可能期望只包含实例方法,但作为一个副作用,还有扩展的类方法
  • 更新


    我添加了一个
    MyConfig
    类,从中创建了一个新实例。这样做的好处是,您可以使用
    config.foo=“foo”

    我对您的代码做了一些修改,以使用我和许多流行的gem(如designe)用于配置的方法。希望您会喜欢:)

    这些变化是:

  • 使用mattr_访问器-它为您的方法创建getter和setter,如果您愿意,您可以选择其中的一些,更多信息
  • configure
    method返回
    self
    ,这样您就可以以一种简单、可读、类似rails的方式配置类
  • 例如:

    Kid.config do |k|
      k.be_kind = false
      k.munch_loudly = true
      k.age = 12
    end
    

    谢谢你的回答!不幸的是,我在sinatra上,没有可用的
    mattr\u访问器。由于我不喜欢使用类变量,我想我定义了一个单独的配置类
    类MyConfig;属性存取器:foo;结束
    ,从中在
    def configure&block
    内创建新实例,分配给
    @config
    ,并传递给块。你怎么认为?
    Kid.config do |k|
      k.be_kind = false
      k.munch_loudly = true
      k.age = 12
    end