将启动实例扩展到类红宝石

时间:2019-06-10 16:23:10

标签: ruby ruby-on-rails-5.2

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 Foo
   extend Boo
end

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

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

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

1 个答案:

答案 0 :(得分:2)

您不能扩展对象*。没有您的实际用例,很难提供确定的答案,因此这里有一些替代方法。

*除非该对象是一个模块,否则请不要在这里获得技术知识。

使用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

使用“动态”委托人

如果您的MyObject类具有动态方法,则可以创建一个动态委托者,该动态委托者将调用MyObject实例的任何公共方法。

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

完全避免元编程

我认为这是元编程的一种不好用法。如果要导航YAML / JSON结构,则应在不使用元编程的情况下进行操作。

例如,给定这样的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