Statt einer Instanzvariable pro Schlüssel, die etwas unnötig sperrigen Code benötigt, warum nicht nur ein Hash wie unten. Auch können define_method
und define_singleton_method
Ihr Freund sein, um schlechtes schlechtes eval
s zu vermeiden.
class MyStorageClass
def initialize
@data = {}
end
def add_entry(key, value)
(@data[key] ||= []) << value
define_singleton_method(key){ @data[key] }
end
def get_entry(key)
@data.key?(key) or raise NoMethodError
@data[key]
end
end
Möglicherweise möchten Sie überprüfen, ob Sie nicht eine vordefinierte Methode überschrieben erste ([email protected]?(key) && self.respond_to?(key)
an der Spitze des add_entry
Methode tun würde), aber das ist für einen anderen Gespräch. Könnte schlecht sein, wenn jemand versucht hat, einen Schlüssel namens inspect
, class
, oder, oh, get_entry
, zum Beispiel, hinzuzufügen!
Sie könnten auch init @ data mit Hash.new {[]}, so dass Sie brauchen nicht auf die, || = Teil in add_entry Verfahren – karina
Gefahr ! Es müsste sein: Hash.new {| h, k | h [k] = []} 'oder alle neuen Schlüssel erhalten Werte, die mit den anderen verknüpft sind. Das Objekt [], das Sie übergeben haben, ist ein einzelnes Objekt im Speicher, auf das von allen Schlüsseln verwiesen wird, und der Operator '<<', den wir verwenden, ändert dieses Objekt an Ort und Stelle. Versuch es! 'h = Hash.new ([]); h [: x] << 1; h [: y] 'gibt dir' [1] '. Normalerweise wende ich mich gegen den Blockinitialisierer für Hash, es sei denn, es ist vorteilhafter als das Speichern eines '|| =' –
Ich habe die geschweiften Klammern verwendet. – karina