【问题标题】:ruby / Passing arguments to a dynamically created classruby / 将参数传递给动态创建的类
【发布时间】:2020-02-22 11:15:33
【问题描述】:

可能还有很多其他更好的方法;但有以下代码:

class ApplicationService
  def self.build(*args, &block)
    new(*args, &block).build
  end
end

class BaseClass; end

class Fetcher < ApplicationService
  attr_reader :resource_name

  def initialize(resource_name)
    @resource_name = resource_name
  end

  def build
    resource_name = @resource_name

    Class.new(BaseClass) do
      @@resource_name = resource_name

      class << self
        def all
          "http://some.remote.resource/#{@@resource_name}/all"
        end
      end
    end
  end
end


为了在self.all 方法中有初始的resource_name,我想出了定义@@resource_name = resource_name。我完全不确定这是否是好方法。

我希望能够使用这样的“生成器”,以便提供以下接口:

## In some kind of initializers :
Xyz = Fetcher.build('xyz')

## Final use :
Xyz.all

是否有更好的模式来动态创建类,同时在创建此类时传递参数?

【问题讨论】:

  • 您是否有理由不想让build 返回BaseClass 的实例?您可以将 all 移动到 BaseClass 并将 resource_name 作为常规实例变量存储在那里
  • @maxpleaner 确实更干净。你如何将resource_name 传递给 BaseClass ?
  • BaseClass.new(resource_name) 或类似的东西

标签: ruby class dynamic


【解决方案1】:

不清楚你为什么要首先创建这个类。如果有充分的理由,我的回答是无效的。

您可以使用“标准”OOP 技术并使用实例来获得所需的行为

class Fetcher
  def initialize(resource_name)
    @resource_name = resource_name
  end

  def all
    "http://some.remote.resource/#{@resource_name}/all"
  end
end

xyz_fetcher = Fetcher.new('xyz')
xyz_fetcher.all

否则,我猜你的代码或多或少是你会/应该做的。只是,我会让Fetcher 类充当单例(不使用Fetcher 的实例):

class Fetcher < ApplicationService
  # make a singleton by privatizing initialize (read this up somewhere else)

  def self.build(resource_name)
    Class.new(BaseClass) do
      @@resource_name = resource_name

      class << self
        def all
          "http://some.remote.resource/#{@@resource_name}/all"
        end
      end
    end
  end
end

然后

Xyz = Fetcher.build('xyz')
Xyz.all

现在,你有 ApplicationService 的东西,它或多或少地实现了这一点(并通过了一个块),所以我们的读者可能错过了大局的某些部分......请澄清是否是这种情况。

除了单例化之外,您还可以使用模块来代替(感谢@max 的评论)。

【讨论】:

  • 图片并没有那么大,因为它只是对类如何详细工作的调查——graphql ruby​​ 向我介绍了一个基于动态类的结构;我在这里只是用普通的类来看看这种方法
  • 关于你回复的第一部分;我同意,不需要有这样的结构来实现这个简单的目标。但同样是试图看看它在动态环境中的表现。感谢单例指针
  • 如果你想让它不可实例化,那么将它声明为一个模块而不是一个类。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-15
  • 1970-01-01
  • 2015-08-06
  • 1970-01-01
  • 1970-01-01
  • 2012-09-12
相关资源
最近更新 更多