加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

ruby – 使用块配置类

发布时间:2020-12-17 01:56:15 所属栏目:百科 来源:网络整理
导读:我有一个基本模块,其中包含一些逻辑,它包含在各种类中.现在我需要一个配置块来设置类的行为方式. 我尝试了以下代码: class MyConfig attr_accessor :foo,:barendmodule BaseModule def self.included base base.include InstanceMethods base.extend ClassM
我有一个基本模块,其中包含一些逻辑,它包含在各种类中.现在我需要一个配置块来设置类的行为方式.

我尝试了以下代码:

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">
  1. I’m unsure if an instance variable @config for a module / class is the best way to configure a class. Is this the right way,or are there any better solutions?
  2. Is it good to also use base.extend ClassMethods when the module only gets included with include BaseModule? A developer could expect that only instance methods get included,but as a side effect there are also class methods extended.

更新

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

解决方法

我已经改变了你的代码以使用我和许多流行的宝石(如设计)用于配置的方法.希望你会喜欢它:)

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

  module ClassMethods
    mattr_accessor :foo
    @@foo = 'initial value'

    def configure &block
      block.call(self)
    end
  end

  module InstanceMethods
    def do_something
      puts foo
    end
  end
end

class MyClass1
  include BaseModule

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

class MyClass2
  include BaseModule

  configure do |klass|
    klass.foo = "bar"
  end
end

MyClass1.new.do_something
# => "foo"
MyClass2.new.do_something
# => "bar"

变化是:

>使用mattr_accessor – 它为您的方法创建getter和setter,如果您愿意,可以选择退出其中一些,更多信息here
>让configure方法返回self,这样你就可以用简单,可读,类似rails的方式配置你的类

例:

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读