将启动的实例扩展到 Class ruby

extend an initiated instance to a Class ruby

class Myobject
  def initialize(numberofcows,numberofdogs)
    @numberofcows = numberofcows
    @numberofdogs = numberofdogs
  end
  def cows
    @numberofcows
  end
  def dogs
     @numberofdogs
  end
end

定义常数:

Boo = Myobject.new(5,10)

扩展 class:

class Foo
   extend Boo
end

如何将所有方法从一个启动的对象扩展到另一个 class?

Foo.cows => 5
Foo.dog  => 10

Myobject 是一个 class,它从 YAML 文件中读取并从中创建方法。它们是应用程序设置。我需要将那些动态分配的方法添加到另一个 class.

您不能扩展对象*。没有您的实际 use-case,很难提供明确的答案,因此这里有一些备选方案。

* 除非该对象是一个模块,但我们不要在这里讨论技术问题。

使用Forwardable

Forwardable模块可以帮助您定义委托人。但是,它不能很好地处理动态对象。

class Foo
  class << self
    extend Forwardable

    def_delegators :my_object, :cows, :dogs

    def my_object
      @my_object ||= MyObject.new(5, 10)
    end
  end
end
Foo.cows # => 5
Foo.dog  # => 10

使用 "dynamic" 委托人

如果您的 MyObject class 有动态方法,您可以创建一个动态委托器,它将调用 MyObject 实例的任何 public 方法。

class Foo
  class << self
    def setting(method)
      my_object.public_send(method)
    end

    private

    def my_object
      @my_object ||= MyObject.new(5, 10)
    end
  end
end
Foo.setting('cows') # => 5
Foo.setting('dogs') # => 10

完全避免meta-programmation

我认为这是 meta-programmation 的错误用法。如果你想导航 YAML/JSON 结构,你应该在没有 meta-programmtion.

的情况下进行

例如,给定一个像这样的 YAML:

---
cows: 5
dogs: 10

你可以这样写。

class Foo
  class << self
    def setting(key)
      settings[key]
    end

    private

    def settings
      @settings ||= YAML.load_file('settings.yaml')
    end
  end
end
Foo.setting('cows') # => 5
Foo.setting('dogs') # => 10