プロジェクト

全般

プロフィール

バグ #1357

完了

定義にブロックを伴う抽出条件に対して演算子「=」を使用すると、抽出条件のブロックが評価されない

Shibafu Midorino さんが5年以上前に追加. 5年以上前に更新.

ステータス:
終了
優先度:
通常
対象バージョン:
プラグイン名:
extract
クラッシュする:
いいえ

説明

defextractcondition でブロックを伴う抽出条件を定義し、抽出タブの絞り込み条件で演算子に「=」を使用するとその抽出条件が評価されなくなります。
この際、評価結果は偽の扱いになりますので、常にその条件ではマッチしなかったことになってしまいます。

経緯

1. 以下のようなプラグインを開発していたところ、debugオプションで起動してもnoticeが出力されておらず、ブロックが全く評価されていないことに気づく。

# -*- coding: utf-8 -*-

Plugin.create(:extract_retweeter) do
  defextractcondition(:retweeter, name: 'リツイートしたユーザ名', operator: true, args: 1) do |argument, message: raise, operator: raise, &compare|
    notice "|||||||| eval extract_retweeter ||||||||" 
    message.retweeted_by.any? { |u| compare.(u.idname, argument) }
  end
end

2. Slackにて情報交換を行い、演算子「=」に問題がある可能性が浮上する。

原因

ブロックを伴う抽出条件の評価に使用されている、extract.rb の Plugin::Extract::Calc クラスが == 演算子を期待通りに処理できていません。

上記経緯のコードで作成された抽出条件を使用し、このような絞り込み条件を設定したとします。
  • いずれかにマッチする: ON
  • リツイートしたユーザ名 = miku (条件1)
  • リツイートしたユーザ名 ≠ yukari (条件2)

すると、extract.rb の compile メソッド内ではMIKU関係の処理を経由して以下のコードが生成されます。

lambda{ |message|
retweeter = Plugin::Extract::Calc.new(message, extract_condition[:retweeter])
  if retweeter == "miku" 
  true
else
  true

  if retweeter.__send__(:!=, "yukari")

    true

  else

    true

    nil

  end
end
}

先に上手く動く方をおさらいすると、条件2は retweeter.__send__(:!=, "yukari") という式になり Plugin::Extract::Calc#method_missing を経由して抽出条件のブロックが評価されます。
(あまり読み込めていないのですが __send__ の第1引数として、演算子が指定されていることと推測しています。)

一方、条件1は retweeter "miku" とコンパイルされています。この場合 Plugin::Extract::Calc#method_missing ではなく演算子の既定動作である Object# のほうが呼ばれてしまいます。
そのため、この式で抽出条件のブロックが評価されることはなく、結果は常に偽となります。

どうしたいか

Plugin::Extract::Calc#== のオーバーライドが必要なのでは?と考えていますが、抽出プラグインの仕組みの理解が浅いので実装には踏み切れていません。
原因と修正先が正しいかをチェックしていただきたいです。

他の形式にエクスポート: Atom PDF