2013-07-29 19 views
0

Что может быть последствия обезьяны ремонтного Hash, чтобы действовать так:обезьяна латание Руби Hash класс

class Hash 
    def method_missing(method,*args, &block) 
    if self.has_key?(method) 
     return self[method] 
    elsif self.has_key?(method.to_s) 
     return self[method.to_s] 
    else 
     return nil 
    end 
    end 
end 

Мое оправдание заключается в следующем:

В принципе, когда я добавить объекты в хэши, я делаю уверен, что их keys.to_s уникальны.

Должен ли я быть обеспокоен, я что-то упустил?

h = { :foo => "bar", "hello" => "bar" } 

h.foo => "bar" 
h.hello => "bar" 
+2

Почему вы не используете 'HashWithIndifferentAccess'? –

+0

Кроме того, я не знал о классе :-), ActiveSupport :: HashWithIndifferentAccess :: HashWithIndifferentAccess требует рельсов. Кроме того, он не разрешает «точечные геттеры» (h.foo, который быстрее вводить, чем h ["foo"] и h [: foo]) – Abdo

+2

«Быстрее набирать» - очень плохая причина для реализации этого ... –

ответ

5

Для этого есть природный рубиновый объект: OpenStruct.

Вы можете создать экземпляр OpenStruct с хешем.

o = OpenStruct.new(hello: 'world') 

После инициализации вы можете использовать все ключи как методы.

o.hello #=> "world" 

Поэтому вам не нужен обезьяний пластырь вашего хэш (что может привести к странному поведению на самом деле).

И OpenStruct управляет внутренними дубликатами между строками и символами.

OpenStruct.new(:hello => 'world', 'hello' => 'world2') #=> #<OpenStruct hello="world2"> 
+3

downside: вы теряете важные методы (например, 'Hash # count',' Hash # keys', 'Hash # values', ... включая большинство методов' Enumerable') – tessi

+0

Интересный класс! Это не позволяет мне использовать существующие объекты Хэша, а также те, которые исходят от других драгоценных камней. Комментарий tessi тоже предупреждает. @tessi, спасибо за это :-) – Abdo

+0

'hash = {hello: 'world'}; o = OpenStruct.new (hash) '<- Вы действительно можете использовать существующие хеши. –

1

BAD IDEA !!

Если вы пропустили какой-либо из допустимых методов хэширования, вы получите нуль вместо отсутствующего реального метода. Например: {} .count => 0, {} .counts => nil вместо NoMethodError: undefined метод `counts 'для {}: Hash.

+2

Это не аргумент против использования этой техники. У вас будет * точно * те же проблемы, если вы используете Hash в первую очередь.Этот метод предназначен для удобства, а не для безопасности метода. – tadman

Смежные вопросы