Errbotの値の置き場周り

少しずつ細々とした部分で使っていきそうなので、少しだけまとめてみる。


## Errbot起動時設定ファイル

Errbotの起動時に指定する設定ファイル。(デフォルトだと`config.py`)
バックエンドやストレージに何を使うかなど、Errbot全体の挙動に影響するものを置くのがメイン。[^1]
`BotPlugin`系のクラスからは`self.bot_config`で参照ができる。

読み込まれたファイルはそのままpythonのモジュールとして扱われるため、実行中内での値変更は可能。
ただし、再起動すれば当然最初の値に戻る。

[^1]: もちろん、それ以外の値もおいてもOK

### コードサンプル

```py3:pluginexample.py
class PluginExample(BotPlugin):
    @botcmd
    def example_admins(self, msg, args):
        return self.bot_config.BOT_ADMINS
```

### 特徴まとめ

- コア設定を置くのに必ず用意するもの
- プラグインからの参照が容易なので、共有したい固定値を置くのに向いている
- 状況が変わると変動するもには向かない


## プラグインのモジュール内変数(インスタンス変数やモジュール変数)

BotPluginクラスを定義するファイルは普通にモジュールとして個別インポートされるので、同一モジュール内の値などは問題なく参照ができる。
ただし、Yapsyを使っているため(?)他のプラグインから参照するのはちょっと現実的ではない。[^2]
こちらも、再起動すれば元の値に戻る。

[^2]: できないことはなさそうだけど、すごく面倒だった記憶がある。

### コードサンプル

```py3:pluginexample.py
MESSAGES = (
    'Hello',
    'Hi',
)

class PluginExample(BotPlugin):
    @botcmd
    def example_msg(self, msg, args):
        return MESSAGES[0]
```

### 特徴まとめ

- プラグイン内でしか使いまわさない固定値を持つのに向いている
    - プラグインで使うURL
- 複数プラグイン間での使い回しには向かない
- 再起動されると最初の値にリセットされるので永続化はできない
    - 逆に永続化されなくても困らない程度のものならインスタンス変数に持たせてもOK(APIのキャッシュとか)


## プラグインの`config`

`get_configuration_template()`を定義してやることでプラグインごとの設定を管理が可能。
ここで扱える設定値はbotに対する専用のコマンドで値を注入することができる。

注入されたconfigは、`self.config`経由でアクセスが可能。
さらに、これについてはstorageに保存されるため、再起動された際にも読み込まれる。

### コードサンプル

```py3:pluginexample.py
class PluginExample(BotPlugin):
    def get_configuration_template(self):
        return {'ID_TOKEN': '00112233445566778899aabbccddeeff',
                'USERNAME':'changeme'}

    @botcmd
    def example_username(self, msg, args):
        return "Hi! I am " + self.config['USERNAME']

```

botcmd例 [^3] [^4]

```
>>> !plugin config PluginExample {'ID_TOKEN' : '00112233445566778899aabbccddeeff', 'USERNAME':'changeme'}
```

[^3]: http://errbot.io/en/latest/user_guide/plugin_development/configuration.html より
[^4]: jsonではなくevalな文法なことに注意

### 特徴まとめ

- プラグイン内でしか使いまわさない変動値を置くのが基本
    - APIを使うプラグインのAPIキーとかはこっちがいい
- 永続化されるので、保存先のstorageアクセス権とかには注意 [^5]

[^5]: 例えば、Firbaseプラグインで永続化すると、jsonベースの管理なのでデータベースに参照できる人は全員設定値を見ることが可能


## プラグインの`data`

[以前書いた](http://qiita.com/attakei/items/e77986da9bb311d5992b)ように、プラグインのインスタンスはそれぞれ独立したストレージ領域を持つことができる。
こちらは`config`と違って専用のコマンドなどはないが、プラグインの挙動の適当なタイミングで随時読み書きが可能。
storageによってリアルタイムで永続化されている。


### コードサンプル

```py3:pluginexample.py
class PluginExample(BotPlugin):
    @botcmd
    def example_put(self, msg, args):
        put['msg'] = 'Test'
        return "pushed"

    @botcmd
    def example_pop(self, msg, args):
        put['msg'] = ''
        return "poped"

    @botcmd
    def example_see(self, msg, args):
        return put.get('msg', None)
```

### 特徴まとめ

- ユーザーのアクションに応じた値なんかを置くのが基本
    - APIを投げた結果とか
    - ユーザーの状態とか
- 永続化されるので、保存先のstorageアクセス権とかには注意 [^5]


## (おまけ)上のであげたコードサンプルを繋げたやつ
```py3:pluginexample.py
from errbot import BotPlugin, botcmd


MESSAGES = (
    'Hello',
    'Hi',
)

class PluginExample(BotPlugin):
    def get_configuration_template(self):
        return {'ID_TOKEN': '00112233445566778899aabbccddeeff',
                'USERNAME':'changeme'}

    @botcmd
    def example_admins(self, msg, args):
        print(self.bot_config)
        # self.bot_config.BOT_ADMINS = ['None']
        return self.bot_config.BOT_ADMINS

    @botcmd
    def example_msg(self, msg, args):
        return MESSAGES[0]

    @botcmd
    def example_username(self, msg, args):
        return "Hi! I am " + self.config['USERNAME']

    @botcmd
    def example_put(self, msg, args):
        self['msg'] = 'Test'
        return "pushed"

    @botcmd
    def example_pop(self, msg, args):
        self['msg'] = ''
        return "poped"

    @botcmd
    def example_see(self, msg, args):
        return self.get('msg', None)
```