Crowdhailer
Creator of Raxx
EDIT: I have written a blog post on this topic
I have been implementing middleware using the defoverridable and super. For example
# myapp.ex
defmodule MyApp do
use Tokumei.Routing
use Tokumei.Exceptions
use Tokumei.ContentLength
use Tokumei.CommonLogger
use Tokumei.MethodOverride
# define routes
end
The Routing module creates a function handle_request/2 and in each middle ware this function is defined as overridable and a new definition created that calls into super as needed. For example the implementation of Tokumei.MethodOverride is as follows, link to code on gihtub.
defmodule Tokumei.MethodOverride do
def override_method(request = %{method: :POST, query: query}) do
{method, query} = Map.pop(query, "_method")
case method && String.upcase(method) do
nil ->
request
method when method in ["PUT", "PATCH", "DELETE"] ->
method = String.to_existing_atom(method)
%{request | method: method, query: query}
end
end
def override_method(request) do
request
end
defmacro __using__(_opts) do
quote do
defoverridable [handle_request: 2]
def handle_request(request, config) do
request = unquote(__MODULE__).override_method(request)
super(request, config)
end
end
end
end
My questions are:
- Is there any cost to repeatedly overriding a function?
- Are there any other libraries doing similar?
- General comments about the approach
Trending in Questions
I’m working on a project that simulates the bumbl example in the programming phoenix book. It acts almost like an email client. We have a...
New
Hello,
I know there is an approach for handling lists that allows for optimized traversal, but I can’t recall the specific method (somet...
New
I’m seeing that a list inside a Kino.DataTable will be interpreted as a charlist, even if the Kino.configure() is set to charlists: :as_l...
New
So my question is quite simple and i have found no conclusive answer on forum, google or AI.
Should we use :erlang.float for Integer to ...
New
Documentation
While reading the Scoped Routes section, I noticed that the documentation currently refers to a problem without explainin...
New
Hi, I’ve just set up an application with ash_authentication. There is only magic link strategy for now, so there is no confirmation add o...
New
If a change or preparation module uses Ash.Changeset.get_argument/2 or Ash.Query.get_argument/2 (or any of the other get_argument functio...
New
Other Trending Topics
I am happy to introduce the very α version of the new programming language compiled to BEAM.
Welcome Cure.
It has literally three kille...
New
Hi there! We created Gust: A task orchestrator inspired by Airflow.
For those who have never heard about Aiflow, it’s a Python-based wor...
New
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
New
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New
With AI doing more of the implementation work, I’ve been wondering how much coding I should deliberately keep doing myself.
My main conc...
New
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #library
- #deployment
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #podcasts
- #javascript
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixirconf-us
- #ai
- #blog-post
- #elixir-ls
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #hex
- #security
- #metaprogramming










Showing Posts 1 to 9- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
OvermindDL1
I hope there is not much cost! I’ve been using a lot of super to override
action/2in controllers to handle exceptions such as redirect’s when a permission exception is thrown. ^.^But yeah, I’ve not looked at how super is implemented, hmm…
So it seems to be implemented at:
https://github.com/elixir-lang/elixir/blob/ff8dd1af7f6b53e482cd8be304093fabd36bc6dc/lib/elixir/src/elixir_overridable.erl#L16-L22
So it looks up the previous function definition and seems to call it, and just above that is where you see it defines in ets the information of what is overridable, with the store function being at the bottom.
So, it looks like the old/parent definitions are defined with a combination of the name and a counter, so always unique, and defp’d, so calls to them are always ‘local’ calls (in erlang parlance), which is fast.
So no issue, it looks like
superis fast, I’d not worry about lots of them at all.Crowdhailer
Well that is great news. I like the way we can have an essentially native middleware solution.
OvermindDL1
Also entirely an implementation detail and you should not do this, but you could ‘directly’ call an older version of a function by using its hidden/internal name (for a ‘blah’ function it would be the function name of
:"blah (overridable #{count})"for whatever count you want to go ‘up in the stack’). ^.^Crowdhailer
josevalim
I will change the private name of the autogenerated function to include a random component just so people don’t do that.
OvermindDL1
Woot! As it should be, as it is it is definitely not safe. ^.^
michalmuskala
It needs to be deterministic, though. You don’t want to generate different
.beamfiles each time the file is compiled, because functions with override get a different random component. The same source should always give the same.beam.OvermindDL1
Can just add the hash of the existing name to the name, that way it still has the counter as well as it has some ‘more’. Though anything non-random (like hash’s) can still be generated other ways, so it is accessible regardless with enough work, but yeah random would be bad for generated files…
Crowdhailer
I have publish the following blog post. Describing how to implement middleware with macros. I have been using this method for a while and it has been useful