расширить инициируемый экземпляр на класс ruby - PullRequest
1 голос
/ 10 июня 2019
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 Ответ

2 голосов
/ 10 июня 2019

Вы не можете расширить объект *.Без вашего фактического варианта использования сложно дать однозначный ответ, поэтому вот несколько альтернатив.

* Если этот объект не является модулем, но давайте не будем здесь разбираться в технических вопросах.

Использование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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...