редактировать:
Как указывалось @mudasobwa , уже существует стандартная реализация, с классом, который использует method_missing
и внутренний объект Hash ...
По-видимому, это поведение очень понравилось многим и нашло путь к стандартной библиотеке.
см. Документацию по адресу OpenStruct.
помнить, чтобы требовать применения с использованием: требуют «» ostruct
оригинальный пост:
Я думаю, что вы могли бы искать решение, основанное на method_missing
.
Возможно, обезьяна заплатит класс Hash за поведение, которое будет имитировать то, что вы хотите.
Вот быстрый грязный патч:
class Hash
def method_missing(name, *args, &block)
# getter for symbole
return self[name] if self.has_key? name
# getter for String
return self[name.to_s] if self.has_key? name.to_s
# setter for adding or editing hash keys,
# using the shortcut hash.key = value.
if name.to_s[-1] == '=' && name.to_s.length > 1
self.[]=(name.to_s[0..-2], *args)
self.[]=(name.to_s[0..-2].to_sym, *args)
return *args
end
# nothing happened? move it up the chain for default behavior.
# (assumes Hash doesn't handle missing methods).
super
end
end
Это будет вести себя как «на лету» добытчика и сеттер. Обратите внимание, что getter будет работать только для существующих свойств и что числа не поддерживаются (только строки и символы).
Также обратите внимание, что символы и строки будут унифицированы - если невозможно использовать символ и строку для разных значений, используя эти приемники/сеттеры. Кроме того, символы будут иметь приоритет.
Лично я бы, вероятно, отказался от такого решения удобства или отказался от подклассификации класса Hash. Я не слишком ухожен с патчами обезьян.
Пожалуйста, никогда не используйте 'method_missing', если вы не можете доказать, что нет другого способа добиться желаемого поведения. Это приводит к штрафам за производительность, почти незаметному коду и внезапным ошибкам. Обработка хэшей определенно не является областью применения. – mudasobwa
@mudasobwa, я вообще согласен - но я не вижу способа создать желаемое поведение без использования этой функции ... и опция 'method_missing' существует по какой-то причине. Например, OpenStruct использует 'method_missing' для реализации этой же функции. – Myst
Я никогда не говорил, что «' method_missing »плохо,« я сказал «не делай этого сам». Как вы [заметили] (https://github.com/rubysl/rubysl-ostruct/blob/2.0/lib/ rubysl/ostruct/ostruct.rb # L175-L188), реализация OpenStruct делает много вещей, таких как проверки и т. д. Недостаточно просто перезаписать 'method_missing'. Например. опуская «reply_to?», один разрывает поиск рубина. В конце концов, 'OpenStruct' выполняет _defines methods_, а не вызывает' method_missing' по каждому запросу. – mudasobwa