2012-01-19 8 views
13

Jestem świadomy tej funkcji zapewnianej przez ActiveSupport.Jak mogę uzyskać dostęp do skrótu stylu JavaScript?

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

Jednak już mam duży skrót i chcę uzyskać dostęp do tego skrótu za pomocą notacji kropkowej. Oto, co próbowałem:

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

To nie zadziałało. Jak mogę to zrobić?

Używam Ruby 1.9.2

Aktualizacja:

Niestety muszę wspomnieć, że nie mogę używać openstruct ponieważ nie mają each_pair metodę, która ma Struct. Nie znam kluczy wcześniej, więc nie mogę użyć openstruct.

+0

Prawie identyczny pytanie http://stackoverflow.com/questions/2240535/ruby-hash-keys-as-methods-on-a-class –

+0

możliwe duplikat [Ruby - klucze Hash do nazw metod?] (http://stackoverflow.com/questions/6423484/ru by-hash-keys-to-method-names) –

Odpowiedz

9

OpenStruct powinien działać dobrze dla tego produktu.

Jeśli chcesz zobaczyć, jak to działa, czy może zrobić wersję dostosowaną, zacznij coś takiego:

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

Szukasz OpenStruct

$ require 'ostruct' 
$ large_hash_obj = OpenStruct.new large_hash 
$ large_hash_obj.boy 
=> "John" 
+0

Niestety, powinienem był wspomnieć, że nie mogę użyć openstruct, ponieważ nie ma on metody each_pair, którą ma Struct. Nie znam kluczy przed ręką, więc nie mogę użyć openstructa. –

4

I created my own gem for this i używam go we wszystkich moich projektach. Wydaje się, aby zrobić to, czego potrzebujesz:

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 

Chciałbym opinie.

3

Jeśli to tylko mały skrypt to bezpieczne rozszerzenie Hash się

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

method_missing to magiczna metoda, która jest wywoływana, gdy kod próbuje wywołać metodę, która nie istnieje. Ruby przechwyci niepowodzenie wywołania w czasie wykonywania i pozwoli ci go obsłużyć, aby twój program mógł się z łatwością przywrócić. Powyższa implementacja próbuje uzyskać dostęp do skrótu za pomocą nazwy metody jako symbolu, używając nazwy metody jako łańcucha znaków i ostatecznie kończy się niepowodzeniem z wbudowanym błędem metody Ruby.

Dla bardziej złożonych aplikacji, gdzie dodanie tego zachowania wszystkich skrótów może złamać inny kod lub third0party perełki, użyć modułu i wydłużenia każde wystąpienie

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

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

i dla większej wygody można nawet propagować moduł w dół zagnieżdżone skrótów

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 
Powiązane problemy