trashyEx
Types in a decorator and accessing Context struct
Hello,
Probably related with macros (since I am learning them bit a bit), but let’s see if I can get some insight in what is going on.
I installed the decorator library (Elixir function decorators — decorator v1.4.0). Then, using a hello-world Phoenix project, I have a generic print decorator, but I would like to have a specific one for %Plug.Conn{}, and it does not work.
PageController:
@decorate print_conn()
def index_specific(%Plug.Conn{} = conn, _params) do
IO.inspect(conn)
render(conn, "index.html")
end
@decorate print()
def index_generic(conn, _params) do
IO.inspect(conn)
render(conn, "index.html")
end
The decorators from HwDecorator:
defmodule HwDecorator do
use Decorator.Define, [print: 0, print_conn: 0]
# at compile-time it does not know if is Plug.Conn
# def print(body, %{args: [%Plug.Conn{} = conn, _params]} = context) do
# so I assume we can work only with arity/2
# alternative, to mark with print_conn
def print(body, %{args: [conn, _params]} = context) do
quote do
IO.puts("Func Conn begin: #{Atom.to_string(unquote(context.name))}")
unquote(body)
IO.puts("Func Conn end: #{Atom.to_string(unquote(context.name))}")
end
end
def print(body, context) do
x = 3
quote do
# IO.inspect(unquote(context), label: "context") <---- WHY:2
IO.puts("Func begin: #{unquote(x)} #{Atom.to_string(unquote(context.name))}")
unquote(body)
IO.puts("Func end: #{Atom.to_string(unquote(context.name))}")
end
end
# This does not work:
# def print_conn(body, %{args: [%Plug.Conn{} = conn, _params]} = context) do. # WHY:1
def print_conn(body, %{args: [conn, _params]} = context) do
quote do
IO.puts("Func Conn type begin: #{Atom.to_string(unquote(context.name))}")
unquote(body)
IO.puts("Func Conn type end: #{Atom.to_string(unquote(context.name))}")
end
end
end
The function receives:
[{:=, [line: 8], [
{:%, [line: 8], [
{:__aliases__, [line: 8], [:Plug, :Conn]}, {:%{}, [line: 8], []}
]},
{:conn, [line: 8], nil}
]},
{:_params, [line: 8], nil}
]
So, I assume it is not matching since %Plug.Conn{} = conn is not the same as all those tuples from above.
I have 2 questions.
- WHY:1: What can be done to achieve using types in the decorator functions? Like, for instance, matching Plug.Conn with the first param? I annotate the type in
index_specificin case it helps, since I imagineindex_genericdoes not know it is Plug.Conn at compile time (where I suspect the macros/decorators are being executed).
== Compilation error in file lib/hw_phoenix_web/controllers/page_controller.ex ==
** (FunctionClauseError) no function clause matching in HwDecorator.print_conn/2
The following arguments were given to HwDecorator.print_conn/2:
# 1
{:__block__, [], [{{:., [line: 9], [{:__aliases__, [line: 9], [:IO]}, :inspect]}, [line: 9], [{:conn, [line: 9], nil}]}, {:render, [line: 10], [{:conn, [line: 10], nil}, "index.html"]}]}
# 2
%Decorator.Decorate.Context{args: [{:=, [line: 8], [{:%, [line: 8], [{:__aliases__, [line: 8], [:Plug, :Conn]}, {:%{}, [line: 8], []}]}, {:conn, [line: 8], nil}]}, {:_params, [line: 8], nil}], arity: 2, module: HwPhoenixWeb.PageController, name: :index}
lib/hw_phoenix/decorator.ex:28: HwDecorator.print_conn/2
(decorator 1.4.0) lib/decorator/decorate.ex:164: Decorator.Decorate.apply_decorator/3
(elixir 1.13.4) lib/enum.ex:2396: Enum."-reduce/3-lists^foldl/2-0-"/3
(decorator 1.4.0) lib/decorator/decorate.ex:128: Decorator.Decorate.decorate/4
(elixir 1.13.4) lib/enum.ex:2396: Enum."-reduce/3-lists^foldl/2-0-"/3
(decorator 1.4.0) expanding macro: Decorator.Decorate.before_compile/1
lib/hw_phoenix_web/controllers/page_controller.ex:1: HwPhoenixWeb.PageController (module)
- WHY:2: Why the
contextvariable cannot be used directly there? It is just an struct. I don’t understand whycontext.argsorcontext.namework, but notcontext.
== Compilation error in file lib/hw_phoenix_web/controllers/page_controller.ex ==
** (CompileError) lib/hw_phoenix_web/controllers/page_controller.ex: invalid quoted expression: %Decorator.Decorate.Context{args: [{:conn, [line: 14], nil}, {:_params, [line: 14], nil}], arity: 2, module: HwPhoenixWeb.PageController, name: :index_two}
Please make sure your quoted expressions are made of valid AST nodes. If you would like to introduce a value into the AST, such as a four-element tuple or a map, make sure to call Macro.escape/1 before
First Post!
trashyEx
Any idea?
Popular in Questions
Why is it that the mnesia database isn’t the most preferred database for use in Elixir/Phoenix?
New
Hello everybody,
usually, I use a 29" ultra-wide monitor for VSCode which can easily accomodate explorer (files panel) + file with code ...
New
I am using the Starship cross-shell prompt – it seems pretty nice, but I get some errors:
[WARN] - (starship::utils): Executing command ...
New
I’m not a pro in using Regex and can’t figure out why the following behaviour happens, especially if we take into account the difference ...
New
Hi! May someone helps me, please!
I have two apps into an umbrella project: the first one is Database, which manages queries, and the se...
New
If I have a string “1000 cfu/ml” . I want to remove the characters and / and space . So the string is like this
"1000"
What is the ...
New
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New
Hello!
Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
New
There are pre-rolled solutions for other frameworks that do work. However, Phoenix does not seem to have these. Have people had good expe...
New
For some reason my phoenix channels are working for me in my local dev environment, but as soon as I deploy via Docker, I get a 403 error...
New
Other popular topics
About me? ( if you have nothing better to do than reading about some random guy in the internet :stuck_out_tongue: )
Hello all, this is ...
New
Good day to you all.
I have been struggling to get a query involving like and ilike to work.
Can anyone assist me on this, please?
pro...
New
This release brings a number of exciting features, including integration with the new Phoenix LiveDashboard and Phoenix LiveView. There h...
New
lets say i have a sample like
a = 20; b = 10;
if (a > b) do
{:ok, "a"}
end
if (a < b) do
{:ok, b}
end
if (a == b) do
{:ok, "equa...
New
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
I asked this very same question on twitter and got some interesting feedback, but I thought it would be a good question to ask here as we...
New
I am VERY much an elixir newbie. I have taken one elixir course and one phoenix course on Udemy. During that course, I saw the instructor...
New
I am trying to run a deploy with docker and I successfully runned with this command:
docker build -t romenigld/blog-prod .
but when I t...
New
I had some trouble figuring out how to make many-to-many associations work. Once I got it working, I wrote a blog post. Because I’m a nov...
New
I wrote this comment on r/haskell, and it’s not popular there. :wink: But I think I’m on to something…
Haskell reminds me of Java, and e...
New
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance








