docs: idiomatic Elixir and Phoenix patterns with verified source citations
Extracted patterns from Elixir core and Phoenix source code with specific file:line citations, then verified all citations against the actual source in a second pass. Structure: - patterns/ — Elixir core patterns (GenServer, errors, data, types, etc.) - phoenix/ — Phoenix-specific patterns and deviations - comparison/ — Elixir vs Phoenix side-by-side - smells/ — Anti-patterns and common mistakes - changelog/ — Daily Elixir/Phoenix PR digest (auto-updated)
This commit is contained in:
+30
-11
@@ -10,7 +10,7 @@ Where Phoenix deliberately differs from Elixir core patterns and why.
|
||||
|
||||
**Phoenix deviation:** The Router uses macros extensively.
|
||||
|
||||
**Source:** `lib/phoenix/router.ex:109-123`
|
||||
**Source:** `lib/phoenix/router.ex:106-128`
|
||||
|
||||
> We use `get`, `post`, `put`, and `delete` to define your routes. We use macros
|
||||
> for two purposes:
|
||||
@@ -31,10 +31,12 @@ Where Phoenix deliberately differs from Elixir core patterns and why.
|
||||
|
||||
**Phoenix deviation:** The Router imports entire modules:
|
||||
|
||||
**Source:** `lib/phoenix/router.ex:274-276`
|
||||
**Source:** `lib/phoenix/router.ex:303-306`
|
||||
|
||||
```elixir
|
||||
import Phoenix.Router
|
||||
|
||||
# TODO v2: No longer automatically import dependencies
|
||||
import Plug.Conn
|
||||
import Phoenix.Controller
|
||||
```
|
||||
@@ -49,13 +51,24 @@ import Phoenix.Controller
|
||||
|
||||
**Phoenix deviation:** Aggressive use of module attribute accumulation.
|
||||
|
||||
**Source:** `lib/phoenix/router.ex:271-280`
|
||||
**Source:** `lib/phoenix/router.ex:297-312`
|
||||
|
||||
```elixir
|
||||
Module.register_attribute(__MODULE__, :phoenix_routes, accumulate: true)
|
||||
@phoenix_pipeline nil
|
||||
Phoenix.Router.Scope.init(__MODULE__)
|
||||
@before_compile unquote(__MODULE__)
|
||||
defp prelude(opts) do
|
||||
quote do
|
||||
Module.register_attribute(__MODULE__, :phoenix_routes, accumulate: true)
|
||||
@phoenix_helpers Keyword.get(unquote(opts), :helpers, true)
|
||||
|
||||
import Phoenix.Router
|
||||
import Plug.Conn
|
||||
import Phoenix.Controller
|
||||
|
||||
# Set up initial scope
|
||||
@phoenix_pipeline nil
|
||||
Phoenix.Router.Scope.init(__MODULE__)
|
||||
@before_compile unquote(__MODULE__)
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
**Why the deviation:** The Router needs to collect ALL routes, then compile them into a single dispatch function. This requires building up state during module compilation, then consuming it all at `@before_compile`.
|
||||
@@ -68,7 +81,7 @@ Phoenix.Router.Scope.init(__MODULE__)
|
||||
|
||||
**Phoenix Channel default:** `:temporary` (never restart).
|
||||
|
||||
**Source:** `lib/phoenix/channel.ex:470-475`
|
||||
**Source:** `lib/phoenix/channel.ex:464-472`
|
||||
|
||||
```elixir
|
||||
def child_spec(init_arg) do
|
||||
@@ -91,7 +104,7 @@ end
|
||||
|
||||
**Phoenix Channel:** Defaults to hibernate after 15 seconds of inactivity.
|
||||
|
||||
**Source:** `lib/phoenix/channel.ex:460`
|
||||
**Source:** `lib/phoenix/channel.ex:459`
|
||||
|
||||
```elixir
|
||||
@phoenix_hibernate_after Keyword.get(opts, :hibernate_after, 15_000)
|
||||
@@ -115,7 +128,7 @@ end
|
||||
|
||||
**Phoenix Endpoint:** Uses `Plug.Builder` — a macro that generates the `call/2` pipeline by chaining plugs at compile time.
|
||||
|
||||
**Source:** `lib/phoenix/endpoint.ex:481-483`
|
||||
**Source:** `lib/phoenix/endpoint.ex:478-480`
|
||||
|
||||
```elixir
|
||||
defp plug() do
|
||||
@@ -136,14 +149,20 @@ end
|
||||
|
||||
**Phoenix exceptions:** Include `plug_status` for HTTP response mapping.
|
||||
|
||||
**Source:** `lib/phoenix/router.ex:7-8`
|
||||
**Source:** `lib/phoenix/router.ex:2-26`
|
||||
|
||||
```elixir
|
||||
defmodule NoRouteError do
|
||||
@moduledoc """
|
||||
Exception raised when no route is found.
|
||||
"""
|
||||
defexception plug_status: 404, message: "no route found", conn: nil, router: nil
|
||||
end
|
||||
|
||||
defmodule MalformedURIError do
|
||||
@moduledoc """
|
||||
Exception raised when the URI is malformed on matching.
|
||||
"""
|
||||
defexception [:message, plug_status: 400]
|
||||
end
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user