Подтвердить что ты не робот

Hash ['key'] to hash.key в Ruby

У меня есть хеш

foo = {'bar'=>'baz'}

Я бы назвал foo.bar #=> 'baz'

Моя мотивация переписывает запрос activerecord в необработанный sql-запрос (используя Model # find_by_sql). Это возвращает хэш с значениями предложения SELECT в виде ключей. Однако мой существующий код зависит от нотации object.method. Я хотел бы сделать минимальную переработку кода. Спасибо.

Изменить: похоже, у Lua есть эта функция:

point = { x = 10, y = 20 }   -- Create new table
print(point["x"])            -- Prints 10
print(point.x)               -- Has exactly the same meaning as line above
4b9b3361

Ответ 1

>> require 'ostruct'
=> []
>> foo = {'bar'=>'baz'}
=> {"bar"=>"baz"}
>> foo_obj = OpenStruct.new foo
=> #<OpenStruct bar="baz">
>> foo_obj.bar
=> "baz"
>>

Ответ 2

То, что вы ищете, называется OpenStruct. Это часть стандартной библиотеки.

Ответ 3

Хорошее решение:

class Hash
  def method_missing(method, *opts)
    m = method.to_s
    if self.has_key?(m)
      return self[m]
    elsif self.has_key?(m.to_sym)
      return self[m.to_sym]
    end
    super
  end
end

Примечание: эта реализация имеет только одну известную ошибку:

x = { 'test' => 'aValue', :test => 'bar'}
x.test # => 'aValue'

Если вы предпочитаете поиск символов, а не поиск строк, замените два условия "если"

Ответ 4

Вместо того, чтобы копировать все данные из хэша, вы можете просто добавить какое-то поведение в Hash для поиска.

Если вы добавите эту проблему, вы добавите Hash для обработки всех неизвестных методов в виде хеш-запросов:

class Hash
  def method_missing(n)
    self[n.to_s]
  end
end

Имейте в виду, что это означает, что вы никогда не увидите ошибок, если вы вызываете неправильный метод в хеше - вы просто получите то, что возвратит соответствующий хэш-поиск.

Вы можете значительно уменьшить проблемы отладки, которые могут привести к тому, что только помещает метод в определенный хеш - или столько же хэшей, сколько вам нужно:

a={'foo'=>5, 'goo'=>6}
def a.method_missing(n)
   self[n.to_s]
end

Другое наблюдение заключается в том, что когда method_missing вызывается системой, он дает аргумент Symbol. Мой код превратил его в String. Если ваши хеш-ключи не являются строками, этот код никогда не вернет эти значения - если вы набираете символы вместо строк, просто замените n на n.to_s выше.

Ответ 5

Для этого есть несколько драгоценных камней. Там мой недавний драгоценный камень, hash_dot, и несколько других драгоценных камней с похожими именами, которые я обнаружил, когда я выпустил свою версию на RubyGems, включая dot_hash.

HashDot позволяет синтаксис точечной нотации, сохраняя при этом проблемы с NoMethodErrors, адресованные @avdi. Он быстрее и более возможен, чем объект, созданный с помощью OpenStruct.

require 'hash_dot'
a = {b: {c: {d: 1}}}.to_dot
a.b.c.d => 1

require 'open_struct'
os = OpenStruct.new(a)
os.b => {c: {d: 1}}
os.b.c.d => NoMethodError

Он также поддерживает ожидаемое поведение при вызове не-методов.

a.non_method => NoMethodError

Пожалуйста, не стесняйтесь сообщать об улучшениях или ошибках в HashDot.