alchemy
alchemy copied to clipboard
[feature | breaking] Better events API
Overview
Current Alchemy.Events
usage:
Events.on_user_ban(:handler)
def handler(user, guild) do
...
end
Suggested usage:
Events.on_user_ban(:handler)
def handler(event = %UserBanEvent{}) do
%{guild: guild, user: user} = event
...
end
Description
All Events.on_***
functions would have their handler function changed from (arg1, arg2, arg3, ... -> any)
to (event -> any)
where event
is a named struct for the specific event e.g. %UserBanEvent{guild: guild, user: user}
.
Justification
The current usage is non-intuitive and awkward to use:
- The function handler has a variable arity depending on specific event that is being listened to. This makes registering a handler an exercise that mandates checking the
Alchemy.Events
documentation, even if you are familiar with the library. - Due to varying arity, you cannot register a handler that may handle multiple event types e.g. treating a message create and a message edit event the same, operating on
content
. - Slightly off-topic, but the same "event handler argument" would be used for a
Events.wait_for/3
function (NYI), an intended general solution to the limitedCogs.wait_for/3
. The usage of that function would be even more confusing, since the arity of thecallback
andcondition
functions you might give, in the current system, change based on the type of event you're listening to. - Event arguments often contain some information that is irrelevant to the purpose of the handler. These arguments cannot just be ignored and instead something like
handler(_, _, _, arg, _)
must occur (e.g. in the case of on_reaction_remove).
Advantages to the suggested usage:
- Event handlers can be re-used for similar events.
- Events can be passed around in the user's application as tangible objects.
- Much more intuitive to use, as arguments can be ignored and there is no fixed order.
- Quality-of-life arguments can be added to the events e.g. where only a
message_id
is given, themessage
can be provided if cached, too. Where only achannel_id
is given, the cachedchannel
,guild_id
andguild
can be provided, too. This is a feature present in many other bot libraries that is not present in Alchemy and makes event handlers considerably more verbose.
Dylan