defmodule MyPipeline do
# We use Plug.Builder to have access to the plug/2 macro.
# This macro can receive a function or a module plug and an
# optional parameter that will be passed unchanged to the
# given plug.
use Plug.Builder
plug Plug.Logger
plug :extract_name
plug :greet, %{my_option: "Hello"}
def extract_name(%Plug.Conn{request_path: "/" <> name} = conn, opts) do
assign(conn, :name, name)
end
def greet(conn, opts) do
conn
|> send_resp(200, "#{opts[:my_option]}, #{conn.assigns.name}")
end
end
The plug is called in iex by Plug.Adapters.Cowboy.http MyPipeline, %{} as a opposed to the first one in the Plug docs Plug.Adapters.Cowboy.http MyPlug, [].
Does this mean that the %{} is a means of passing a parameter to the plug(an empty map in this case), whereas the [] means you are passing no parameters to the plug or that it takes no parameters?
Does the expression Plug.Adapters.Cowboy.http mean that every item to the right of a dot is a submodule, making Adapters a submodule of Plug and Cowboy a submodule of the adapters which uses the Cowboy package, and http a submodule of the Cowboy package?
I take it that in the expression %Plug.Conn{}, Conn is a struct defined in the Plug package. Why wouldnât it be right to write it as Plug.%Conn{}
In the case of the code below does it that the extract_name function would not be called if the request did not match "/" <> name? i.e. a plug will not be executed if it pattern it is matched on is not part of the request?
def extract_name(%Plug.Conn{request_path: â/â <> name} = conn, opts) do
assign(conn, :name, name)
end
When a plug is initâd its init/2 function is called if a module or the second argument is it, the second argument is the second argument, so for the call plug :greet, %{my_option: "Hello"} then greetâs second argument will be %{my_option: "Hello"}, it can be whatever the plug wants, so a map, a list, an integer, whatever.
To be âtechnicalâ, the EVM has no such thing as submodules, the Plug.Adapters.Cowboy is a module name, dots and all. Elixir gives you functionality that emulates submodules via dots though, so in essence you can consider it yes, except in this cast http is not a submodule but a function on Plug.Adapters.Cowboy since it starts with a lower-case char.
Because that would basically be doing %Conn{} then calling it on the Plug module. In Elixir a string of initially upper-cased atoms are all combined into a single atom, and âthatâ can then be called with a trailing dot to access the module and whatever is after that is what is accessed. Basically if Plug.%Conn{} compiled (I doubt it does but not tried) it would be trying to call a function named %Conn on the module Plug with the argument of the empty tuple {} or something like that, but since I doubt it compiled, eh⊠^.^
If you surround code in standard markdown code fences (``` on empty lines before and after the code) it will format properly.
The extract name function will still be called, however if the argument does not match what is specified there then it will go to the next same-named/arity function, if no more then it throws an exception.