代码之家  ›  专栏  ›  技术社区  ›  Ben

ruby/向动态创建的类传递参数

  •  2
  • Ben  · 技术社区  · 5 年前

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

    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
    
    
    

    为了得到首字母 resource_name self.all 方法,我想出了定义 @@resource_name = resource_name 是的。我完全不确定这是不是个好办法。

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

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

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

    1 回复  |  直到 5 年前
        1
  •  1
  •   Felix yogesh kumar Panchal    5 年前

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

    您可以使用“标准”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 类充当单例(不使用 取样器 )以下内容:

    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 这或多或少地实现了(并通过了一个街区),所以我们读者可能会错过一些更大的画面…如果是这样,请澄清。