【发布时间】:2017-01-22 06:59:25
【问题描述】:
我正在尝试围绕ExIrc 做一个小包装,但我遇到了一些问题。 __using__ 宏将 ast 附加到模块的开头,我想将函数定义附加到默认 handle_info 的末尾。我可以在每个使用该包装器的模块中手动执行此操作,但我非常确定我会在某个时候忘记这一点。
我当前的包装器实现:
defmodule Cgas.IrcServer do
defmacro __using__(opts) do
quote do
use GenServer
alias ExIrc.Client
require Logger
defmodule State do
defstruct host: "irc.chat.twitch.tv",
port: 6667,
pass: unquote(Keyword.get(opts, :password, "password")),
nick: unquote(Keyword.get(opts, :nick, "uname")),
client: nil,
handlers: [],
channel: "#cohhcarnage"
end
def start_link(client, state \\ %State{}) do
GenServer.start_link(__MODULE__, [%{state | client: client}])
end
def init([state]) do
ExIrc.Client.add_handler state.client, self
ExIrc.Client.connect! state.client, state.host, state.port
{:ok, state}
end
def handle_info({:connected, server, port}, state) do
Logger.debug(state.nick <> " " <> state.pass)
Client.logon(state.client, state.pass, state.nick, state.nick, state.nick)
{:noreply, state}
end
def handle_info(:logged_in, config) do
Client.join(config.client, config.channel)
{:noreply, config}
end
end
end
end
还有一个使用它的示例模块:
defmodule Cgas.GiveAwayMonitor do
use Cgas.IrcServer,
nick: "twitchsniperbot",
password: "token"
require Logger
def handle_info({_type, msg, %ExIrc.SenderInfo{user: "cohhilitionbot"} , _channel}, state) do
if String.downcase(msg) |> String.contains?("giveaway") do
IO.inspect msg
end
{:noreply, state}
end
end
在当前状态下,由于 IRC 随机消息,我不关心它迟早会崩溃。
我需要在文件末尾附加类似的东西来处理所有随机情况:
def handle_info(_msg, state) do
{:noreply, state}
end
【问题讨论】:
标签: macros metaprogramming elixir