2018年12月10日月曜日

function+table


config.luaの21~23行目
local error = error or print+{'Error:'} local warning = warning or print+{'Warning:'} local notice = notice or print+{'Notice:'}
この「print+{ほにゃらら}」がわけわかめなので調べました。

答えはWindower4\addons\libs\functions.luaの227行目。

-- Assigns a metatable on functions to introduce certain function operators.
-- * fn+{...} partially applies a function to arguments.
-- * fn-{...} partially applies a function to arguments from the end.
-- * fn1..fn2 pipes input from fn2 to fn1.
debug.setmetatable(functions.empty, {
    __index = index,
    __add = add,
    __sub = sub,
    __concat = functions.pipe,
    __unm = functions.negate,
    __class = 'Function'
})

関数の演算子をオーバーロードしてました。+演算子なので__addですね。汎関数(高階関数)は引数として関数を受け取りますが、関数だけでなくその引数も一緒に受け取るイメージです。

たとえば local error = print+{'Error:'} だとして、

 error('a', 'b', 'c')

を実行するとprint('Error:', 'a', 'b', 'c')が実行されるわけです。



マイナス演算子の場合は、local error2 = print-{'Error:'} だとして、

 error2('a', 'b', 'c')

を実行するとprint('a', 'b', 'c', 'Error:')が実行されます。決まり文句を文頭か文末に付け加えるときに便利ってことでしょうか。



これだけだとイマイチこの記法を使う意図がわかりづらいですが、この記法が本領を発揮するのは、たとえば、こんな場合。
require('sets') filter = S{     '* does not have enough *',     'Unable to use *',     '* Left: *',     '* can only use that command during *', } windower.register_event('incoming text', function(text)     return filter:any(windower.wc_match+{text}) end)  
これは、英語フォーラムに投稿されたスクリプトです。日本語クライアントでプレイしているとき、以下のようなメッセージが出てイライラしたりしますよね。

  そのコマンドは実行できない。
  少し時間をおいてから実行してください。


英語フォーラムで提案されていたのは、こういうイライラさせるメッセージをフィルターして出さないようにするスクリプトです。クライアントに送られてくるテキストメッセージのフィルタリングをWindowerの'incoming text'イベントハンドラーを使って実装しています。

'incoming text'の仕様は良く分からないのですが、おそらくreturn trueするとそのメッセージがフィルタされて見えなくなるようです。anyという関数はfunctions.luaで定義されています。wc_matchはワイルドカードの文字列マッチングで、Windowerのwikiに説明がありました

似たようなアイデアはネ実にもありました。


0 件のコメント:

コメントを投稿