Вы не можете расширить объект *.Без вашего фактического варианта использования сложно дать однозначный ответ, поэтому вот несколько альтернатив.
* Если этот объект не является модулем, но давайте не будем здесь разбираться в технических вопросах.
Использование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