もぐてっく

人は1つ歳をとるたび、1ビットづつ大きくなれると信じてた。

mikutter 3.6のSpellのメモ

スペル(Spell)って?

まだよくわからぬ。
mikutter内の「動作」を柔軟に抽象化する仕組みだと思います。

仕様

スペルはdefspellと言うDSLとして定義されています。

$(MIKUTTER_DIR)/core/plugin/spell/spell.rb

defdsl :defspell do |spell_name, *constraint, condition: nil, &block|

spell_name

スペル名をシンボルで指定します。
例えば「投稿」は:composeです。

constraint

そのスペルに関わるモデルのslugを適当に並べて指定します。

みたいな。

condition

そのスペルが今発動できるか否かを返すlambdaを渡します。
procにはconstraintに指定したモデルのインスタンスが渡されます。
発動可能ならtrue、ダメならfalseを返しましょう。

block

スペルを発動した時に行う処理です。

スペルの呼び出し方

任意のPluginのインスタンスにスペル名と同名のメソッド(「compose()」の様な)があるので、それを呼びます。

引数には関係するモデルのインスタンス、オプションたち(ハッシュ)を適当な順番で渡せばいいみたいです。引数にnilがあっても大丈夫っぽいです。

$(MIKUTTER_DIR)/core/mui/gtk_postbox.rb

@posting = Plugin[:gtk].compose(
current_world,                                     # :twitterモデルのインスタンス
to_display_only? ? nil : @to.first,         # 送り先があるならそのモデルのインスタンス
body: text,                                           # オプション
visibility: @visibility                             # オプション
).next{

発動可能なスペルが存在するかを事前にチェックするには、「スペル名?」と言うメソッド(「compose?()」の様な)があるので、それを呼びます。

Plugin[:gtk].compose?(current_world, to_display_only? ? nil : @to.first, visibility: @visibility)

スペルの呼び出され方

$(MIKUTTER_DIR)/core/plugin/twitter/twitter.rb

defspell(:compose, :twitter,・・・・) do |twitter, body:, to: nil, **options|

ブロックの引数の種類に意味合いがあるので注意が必要です。
($(MIKUTTER_DIR)/core/plugin/spell/struct.rb"でやってます。)

  • twitter:普通の引数(req)
  • body:キーワード引数(keyreq)
  • to:デフォルト値ありのキーワード引数(key)
  • options:残りのキーワード引数(keyrest)

普通の引数(req)、デフォルト値ありの普通の引数(opt)

constraintに指定したモデルのインスタンス
(多かったり少なかったりすると例外が発生します*1

デフォルト値ありのキーワード引数(key)

スペルのオプションに同名のキーがある場合、それが代入されます。

キーワード引数(keyreq)

スペルのオプションに同名のキーがある場合、それが代入されます。同名のキーが無い場合は例外が発生します(*1)

残りのキーワード引数(keyrest)

オプションの内容が全部渡されます。

メモ

発動するスキルは次の条件で発見されます。

  • 呼び出し側が引数に指定したモデルと、スペル側のconstraintが完全に一致していること。⇒スペルのconditionが実行される。
  • conditionの結果がtrueであること。

*1:Plugin::Spell::ArgumentErrorが発生してるはずなんですがmikutterが落ちるわけでも--debugでもログが出るわけでもなく。謎です。