alchemy icon indicating copy to clipboard operation
alchemy copied to clipboard

[feature | breaking] Better events API

Open curz46 opened this issue 5 years ago • 0 comments

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 limited Cogs.wait_for/3. The usage of that function would be even more confusing, since the arity of the callback and condition 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, the message can be provided if cached, too. Where only a channel_id is given, the cached channel, guild_id and guild 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

curz46 avatar Jul 02 '19 20:07 curz46