crystal icon indicating copy to clipboard operation
crystal copied to clipboard

Allow method overloads for `enum` members

Open jgaskins opened this issue 1 year ago • 1 comments

I've found myself writing a lot of event-handling code recently. When an event comes in over a webhook (GitHub integrations, Stripe subscriptions), I often pass it off to a method so I can lean on method overloading to route the event to its handler:

abstract struct Event
  include JSON::Serializable

  use_json_discriminator "type", {
    create: Create,
    update: Update,
    delete: Delete,
  }

  struct Create < self
    # ...
  end

  struct Update < self
    # ...
  end

  struct Delete < self
    # ...
  end
end

def handle(create : Event::Create)
end

def handle(update : Event::Update)
end

def handle(delete : Event::Delete)
end

In some of these integrations, I need to do the same sort of routing on the value of an enum, and I think it would be nice if Crystal supported the same pattern there:

enum Action
  Create
  Update
  Delete
end

def handle(create : Action::Create)
end

def handle(update : Action::Update)
end

def handle(delete : Action::Delete)
end

In both cases, it saves the programmer from having to write an intermediate case … in statement to perform the routing. Depending on complexity, you're probably delegating the handler logic to another method anyway:

enum Action
  Create
  Update
  Delete
end

def handle(action : Action)
  case action
  in .create?
    handle_create
  in .update?
    handle_update
  in .delete?
    handle_delete
  end
end

def handle_create
end

def handle_update
end

def handle_delete
end

If we can use enum members as method overloads, we can lean on a construct that automatically guarantees that all cases are handled which is already used for inheritance.

jgaskins avatar Oct 07 '24 03:10 jgaskins