class Irc::Bot::Registry::Accessor
This class provides persistent storage for plugins via a hash interface. The default mode is an object store, so you can store ruby objects and reference them with hash keys. This is because the default store/restore methods of the plugins’ RegistryAccessor are calls to Marshal.dump and Marshal.restore, for example:
blah = Hash.new blah[:foo] = "fum" @registry[:blah] = blah
then, even after the bot is shut down and disconnected, on the next run you can access the blah object as it was, with:
blah = @registry[:blah]
The registry can of course be used to store simple strings, fixnums, etc as well, and should be useful to store or cache plugin data or dynamic plugin configuration.
WARNING: in object store mode, don’t make the mistake of treating it like a live object, e.g. (using the example above)
@registry[:blah][:foo] = "flump"
will NOT modify the object in the registry - remember that Registry#[] returns a Marshal.restore’d object, the object you just modified in place will disappear. You would need to:
blah = @registry[:blah] blah[:foo] = "flump" @registry[:blah] = blah
If you don’t need to store objects, and strictly want a persistant hash of strings, you can override the store/restore methods to suit your needs, for example (in your plugin):
def initialize class << @registry def store(val) val end def restore(val) val end end end
Your plugins section of the registry is private, it has its own namespace (derived from the plugin’s class name, so change it and lose your data). Calls to registry.each etc, will only iterate over your namespace.
This class provides persistent storage for plugins via a hash interface. The default mode is an object store, so you can store ruby objects and reference them with hash keys. This is because the default store/restore methods of the plugins’ RegistryAccessor are calls to Marshal.dump and Marshal.restore, for example:
blah = Hash.new blah[:foo] = "fum" @registry[:blah] = blah
then, even after the bot is shut down and disconnected, on the next run you can access the blah object as it was, with:
blah = @registry[:blah]
The registry can of course be used to store simple strings, fixnums, etc as well, and should be useful to store or cache plugin data or dynamic plugin configuration.
WARNING: in object store mode, don’t make the mistake of treating it like a live object, e.g. (using the example above)
@registry[:blah][:foo] = "flump"
will NOT modify the object in the registry - remember that Registry#[] returns a Marshal.restore’d object, the object you just modified in place will disappear. You would need to:
blah = @registry[:blah] blah[:foo] = "flump" @registry[:blah] = blah
If you don’t need to store objects, and strictly want a persistant hash of strings, you can override the store/restore methods to suit your needs, for example (in your plugin):
def initialize class << @registry def store(val) val end def restore(val) val end end end
Your plugins section of the registry is private, it has its own namespace (derived from the plugin’s class name, so change it and lose your data). Calls to registry.each etc, will only iterate over your namespace.
Attributes
Public Class Methods
plugins don’t call this - a Registry::Accessor
is created for them and is accessible via @registry.
# File lib/rbot/registry/bdb.rb, line 330 def initialize(bot, name) @bot = bot @name = name.downcase @filename = @bot.path 'registry', @name dirs = File.dirname(@filename).split("/") dirs.length.times { |i| dir = dirs[0,i+1].join("/")+"/" unless File.exist?(dir) debug "creating subregistry directory #{dir}" Dir.mkdir(dir) end } @filename << ".db" @registry = nil @default = nil @recovery = nil # debug "initializing registry accessor with name #{@name}" end
Public Instance Methods
lookup a key in the registry
# File lib/rbot/registry/bdb.rb, line 403 def [](key) if File.exist?(@filename) && registry.has_key?(key) return restore(registry[key]) else return default end end
set a key in the registry
# File lib/rbot/registry/bdb.rb, line 412 def []=(key,value) registry[key] = store(value) end
empties the registry (restricted to your namespace)
# File lib/rbot/registry/bdb.rb, line 515 def clear return true unless File.exist?(@filename) registry.clear end
# File lib/rbot/registry/bdb.rb, line 360 def close # debug "closing registry #{registry}" return if !@registry registry.close end
# File lib/rbot/registry/bdb.rb, line 422 def default @default && (@default.dup rescue @default) end
delete a key from the registry
# File lib/rbot/registry/bdb.rb, line 483 def delete(key) return default unless File.exist?(@filename) return registry.delete(key) end
just like Hash#each
# File lib/rbot/registry/bdb.rb, line 427 def each(set=nil, bulk=0, &block) return nil unless File.exist?(@filename) registry.each(set, bulk) {|key,value| block.call(key, restore(value)) } end
just like Hash#each_key
# File lib/rbot/registry/bdb.rb, line 435 def each_key(set=nil, bulk=0, &block) return nil unless File.exist?(@filename) registry.each_key(set, bulk) {|key| block.call(key) } end
just like Hash#each_value
# File lib/rbot/registry/bdb.rb, line 443 def each_value(set=nil, bulk=0, &block) return nil unless File.exist?(@filename) registry.each_value(set, bulk) { |value| block.call(restore(value)) } end
# File lib/rbot/registry/bdb.rb, line 353 def flush # debug "fushing registry #{registry}" return if !@registry registry.flush registry.sync end
# File lib/rbot/registry/tc.rb, line 523 def getlist(key) return [] unless File.exist?(@filename) (registry.getlist(key.to_s) || []).map {|v| restore(v)} end
just like Hash#has_both?
# File lib/rbot/registry/bdb.rb, line 460 def has_both?(key, value) return false unless File.exist?(@filename) return registry.has_both?(key, store(value)) end
just like Hash#has_key?
# File lib/rbot/registry/bdb.rb, line 451 def has_key?(key) return false unless File.exist?(@filename) return registry.has_key?(key) end
just like Hash#has_value?
# File lib/rbot/registry/bdb.rb, line 466 def has_value?(value) return false unless File.exist?(@filename) return registry.has_value?(store(value)) end
just like Hash#index?
# File lib/rbot/registry/bdb.rb, line 472 def index(value) return nil unless File.exist?(@filename) ind = registry.index(store(value)) if ind return ind else return nil end end
returns a list of your keys
# File lib/rbot/registry/bdb.rb, line 489 def keys return [] unless File.exist?(@filename) return registry.keys end
returns the number of keys in your registry namespace
# File lib/rbot/registry/bdb.rb, line 536 def length self.keys.length end
That is btree!
# File lib/rbot/registry/tc.rb, line 515 def putdup(key, value) registry.putdup(key.to_s, store(value)) end
# File lib/rbot/registry/tc.rb, line 519 def putlist(key, values) registry.putlist(key.to_s, value.map {|v| store(v)}) end
# File lib/rbot/registry/bdb.rb, line 349 def registry @registry ||= DBTree.new @bot, "registry/#{@name}" end
restores object from string form, restore(store(val)) must return val. If you override store, you should override restore to reverse the action. For example, if you always just handle strings use:
def restore(val) val end
# File lib/rbot/registry/bdb.rb, line 384 def restore(val) begin Marshal.restore(val) rescue Exception => e error _("failed to restore marshal data for #{val.inspect}, attempting recovery or fallback to default") debug e if defined? @recovery and @recovery begin return @recovery.call(val) rescue Exception => ee error _("marshal recovery failed, trying default") debug ee end end return default end end
set the default value for registry lookups, if the key sought is not found, the default will be returned. The default default (har) is nil.
# File lib/rbot/registry/bdb.rb, line 418 def set_default (default) @default = default end
convert value to string form for storing in the registry defaults to Marshal.dump(val) but you can override this in your module’s registry object to use any method you like. For example, if you always just handle strings use:
def store(val) val end
# File lib/rbot/registry/bdb.rb, line 373 def store(val) Marshal.dump(val) end
# File lib/rbot/registry/bdb.rb, line 531 def sub_registry(prefix) return Accessor.new(@bot, @name + "/" + prefix.to_s) end
Return an array of all associations [key, value] in your namespace
# File lib/rbot/registry/bdb.rb, line 495 def to_a return [] unless File.exist?(@filename) ret = Array.new registry.each {|key, value| ret << [key, restore(value)] } return ret end
Return an hash of all associations {key => value} in your namespace
# File lib/rbot/registry/bdb.rb, line 505 def to_hash return {} unless File.exist?(@filename) ret = Hash.new registry.each {|key, value| ret[key] = restore(value) } return ret end
returns an array of the values in your namespace of the registry
# File lib/rbot/registry/bdb.rb, line 522 def values return [] unless File.exist?(@filename) ret = Array.new self.each {|k,v| ret << restore(v) } return ret end