Tutorial on plugins

« Tutorial 3 Tutorial 5 »

Intent

The last version turns out to be annoying. Being greeted is nice. But being greeted everytime can annoy. We want the bot to remember whom he greeted in order to only greet that person once.

code 1.4.1

extend OnHandlers configuration( "seen" => {} ) def on_join(listener, nick, channel) unless plugin.config["seen"][nick] then answer("welcome in #{channel}, #{nick}") plugin.config.synchronize { seen = plugin.config["seen"] seen[nick] = true plugin.config["seen"] = seen } end end

Explanation

The initial call to 'configuration' tells butler how this plugins config file should look if it doesn't exist yet. It initializes the config file.
In the on_join, the method 'plugin' is simply an alias to 'class' (it's less to type and semantically nicer than self.class). The plugin class inherits (from Butler::Plugin) the class method 'config', which provides the section of butlers configuration only belonging to that plugin.
All we do now is store a nick we've seen in the config-file, abusing it as a database.

You probably wonder about why setting plugin.config["seen"][nick] = true is wrapped into this rather big synchronize block and not just written like shown in 1.4.2. Plugin.config is not a Hash but a ConfigProxy. ConfigProxy#[] returns an ordinary ruby object. If that object is changed, the ConfigProxy instance can't observe that, so the change is not saved. Since the object is detached from the ConfigProxy you can't even do something like: plugin.config[key].mutate; plugin.config[key].save! It is necessary that you assign a value to a key in plugin.config if you want it saved.
The synchronize block is necessary to avoid inconsistent state of the configuration data. Since plugins are executed threaded, multiple users can call them at the same time and they are indeed executed parallely. The synchronize command prohibits multiple parallely executed instances of the plugin to enter the block simultaneously. That means the block within synchronize is guaranteed to be only executed by one plugin at the same time.

code 1.4.2

plugin.config["seen"][nick] = true
« Tutorial 3 Tutorial 5 »

Valid XHTML, 2008-21-05 21:22 CEST