Как я могу получить хеш-доступ в стиле JavaScript? - PullRequest
13 голосов
/ 20 января 2012

Мне известна эта функция, предоставляемая ActiveSupport.

h = ActiveSupport::OrderedOptions.new
h.boy = 'John'
h.girl = 'Mary'
h.boy  # => 'John'
h.girl # => 'Mary'

Однако у меня уже есть большой хэш, и я хочу получить доступ к этому хэшу, используя точечную запись. Вот что я попробовал:

large_hash = {boy: 'John', girl: 'Mary'}
h = ActiveSupport::OrderedOptions.new(large_hash)
h.boy # => nil

Это не сработало. Как я могу сделать эту работу.

Я использую ruby ​​1.9.2

Обновление:

Извините, я должен был упомянуть, что не могу использовать openstruct, потому что у него нет метода each_pair, который есть у Struct. Я не знаю ключей заранее, поэтому не могу использовать openstruct.

Ответы [ 4 ]

9 голосов
/ 20 января 2012

OpenStruct должен хорошо работать для этого.

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

h = { 'boy' => 'John', 'girl' => 'Mary' }

class << h
  def method_missing m
    self[m.to_s]
  end
end

puts h.nothing
puts h.boy
puts h.girl
6 голосов
/ 20 января 2012

Вы ищете OpenStruct

$ require 'ostruct'
$ large_hash_obj = OpenStruct.new large_hash
$ large_hash_obj.boy
=> "John"
4 голосов
/ 20 января 2012

Я создал свой собственный драгоценный камень для этого , и я использовал его во всех своих проектах.Кажется, делает только то, что вам нужно:

large_hash = { boy: 'John', girl: 'Mary' }
r = Ribbon.wrap large_hash

r.boy
 => "John"

r.girl
 => "Mary"

r.keys
 => [:boy, :girl]

r.each_pair { |key, value| puts "#{key} => #{value}" }
boy => John
girl => Mary

Буду рад обратной связи.

3 голосов
/ 01 декабря 2013

Если это всего лишь небольшой скрипт, его можно расширить Hash

class Hash
  def method_missing sym,*
    fetch(sym){fetch(sym.to_s){super}}
  end
end

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

Для более сложных приложений, где добавление этого поведения ко всем хэшам может нарушить другой код или гемы третьих сторон, использовать модуль и расширять каждый экземпляр

module H
  def method_missing sym,*
    fetch(sym){fetch(sym.to_s){super}}
  end
end

the = { answer: 42 }
the.extend(H)
the.answer # => 42

и для большего удобства вы можете даже распространять модуль до вложенных хэшей

module H
  def method_missing sym,*
    r = fetch(sym){fetch(sym.to_s){super}}
    Hash === r ? r.extend(H) : r
  end
end 

the = { answer: { is: 42 } }
the.extend(H)
the.answer.is # => 42
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...