Школьные руины творчества *
* «Руины» означает «потенциально руины»
Конечно, школьное образование необходимо! Каждый должен научиться чему-то, прежде чем сможет его использовать - однако все те прекрасные идеи, которые у вас были о том, как сделать определенную стратегию для конкретной области бизнеса, могут быть легко брошены в нашу глубокую пустоту, если мы не будем осторожны .
По мере того, как вы изучаете новые вещи и приобретаете новые навыки, вы также формируете свое мышление в отношении этих новых вещей и навыков, поскольку они, очевидно, являются «способом сделать это». Будучи людьми, мы склонны прислушиваться к авторитетам - будь то учитель, консультант, сотрудник или даже сайт / форум, который вам нравится. Мы должны ВСЕГДА знать об этом "недостатке" в том, как работает наш разум. Слушайте, что говорят другие люди, но не принимайте то, что они говорят как должное. Всегда придерживайтесь критической точки зрения в отношении каждой новой информации, которую вы получаете.
Вместо того, чтобы думать «Ух ты, это умно. Я буду использовать это с этого момента», нам следует подумать «Ух ты, это умно. Теперь, как я могу использовать это в своем личном наборе навыков и идей»
. Вы можете взглянуть на мой гем moneta
, который представляет собой ORM-вещь для всех видов хранилищ ключей и значений. Вы можете увидеть это по адресу: http://github.com/wycats/moneta/tree/master
Основная идея moneta заключается в том, что все KVS должны вести себя точно так же, как подмножество обычных хэшей Ruby. Мы поддерживаем:
#[]
#[]=
#delete
#fetch
#key?
#store
#update_key
#clear
Методы store
и update_key
принимают дополнительный хэш параметров, который можно использовать следующим образом:
cache = Moneta::Memcache.new(:server => "localhost:11211", :namespace => "me")
cache.store("name", "wycats", :expires_in => 2)
cache.update_key("name", :expires_in => 10)
Мы поддерживаем большое количество KVS:
Каждый магазин поддерживает срок действия, либо изначально (как в memcached), либо с использованием стандартного модуля, который имитирует истечение срока действия в стиле memcache. API всегда идентичен, и существует общая спецификация, с которой работают все адаптеры для обеспечения соответствия.
Также довольно легко добавить свой собственный адаптер, поэтому существует так много их.
Я не знаю ни одного адаптера, подобного Ruby ActiveRecord для Memcached. Подобную библиотеку, вероятно, будет сложно создать, потому что Memcached не действует как реляционная база данных.
В результате библиотека не сможет реализовать около 80% функций, поддерживаемых ActiveRecord, так что выгода от такой реализации? У вас уже есть все, что вам нужно в Rails для работы с memcache с шаблоном "CRUD".
Rails.cache.read('key')
Rails.cache.write('key', 'value')
Rails.cache.delete('key')
Rails.cache.increment('key', 5)
Rails.cache.fetch('key') { 'value' }
Если вам удобнее, вы можете создать оболочку и проксировать эти методы с помощью соответствующих новых методов / create / update / save / destroy. Однако вы никогда не сможете выйти за рамки базовой CRUD-системы только потому, что Memcached не предназначен для использования в качестве реляционной базы данных.
Реализовать довольно просто.
require 'ostruct'
require 'active_support/cache'
class StoredStruct < OpenStruct
attr_writer :store
def self.store
@store || superclass.store
end
def self.expand_key(key)
'StoredStruct_' + (superclass == OpenStruct ? '' : "#{self}_") + key.to_s
end
def self.get_unique_id
key = expand_key('unique_id')
store.write(key, 0, :unless_exist => true)
store.increment(key)
end
def self.save(instance)
id = instance.id || get_unique_id
store.write(expand_key(id), instance)
id
end
def self.find(id)
store.read(expand_key(id))
end
attr_reader :id
def attributes
@table
end
def attributes=(hash)
@table = hash
end
def new_record?
self.id.nil?
end
def save
@id = self.class.save(self)
true
end
def reload
instance = self.class.find(self.id)
self.attributes = instance.attributes unless self == instance
self
end
end
Используйте это так:
# connect to memcached
StoredStruct.store = ActiveSupport::Cache::MemCacheStore.new("localhost:11211")
class Apple < StoredStruct
end
fruit = Apple.new
fruit.color = "red"
fruit.taste = "delicious"
fruit.id
#=> nil
fruit.save
#=> true
fruit.id
#=> 1
# to load any changes:
fruit.reload
Apple.find(1)
#=> fruit