-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Broken compilation #41
Comments
Yup definitely a bug in decorator. If you check out the main branch atm you should have access to an This replaces It works by overriding the def my_fun do
... sibyl code to emit event start ...
super() # actually whatever was passed into the `def` macro, but its the same idea
after
... sibyl error event emission ...
catch
... sibyl catch event emission ...
end I admit that I'm unsure if this works OOTB with |
Although now that I think about it...
I believe if you have Might be a less invasive approach? But then I'm not sure how defoverridable works in tandem with functions with multiple clauses plus default args... |
I would say that is actually more sane than decorator's approach Thx, I'll try it out shortly |
I was able to fix defmodule Helpers.Sibyl do
defmacro __using__(:decorate_all) do
quote do
@before_compile unquote(__MODULE__)
end
end
defmacro __before_compile__(_env) do
quote do
use Sibyl
@decorate_all {Sibyl.Decorator, :trace, []}
end
end
end note the expanded
It would fail to decorate custom def's.
This approach might be better, but it would restrict its use to Two alternative approaches were revealed to me (in a dream):
|
Could you elaborate on what you mean by "custom def"? |
e.g. the module I have in my project for defining runtime-configurable defmodule DI do
defmacro __using__(opts) do
quote location: :keep, generated: true do
import unquote(__MODULE__)
@app unquote(opts)[:app] || Mix.Project.config()[:app]
@path unquote(opts)[:path] || [__MODULE__, :impl]
def impl, do: Utils.Application.fetch_env!(@app, @path)
defoverridable impl: 0
end
end
defmacro defdi({name, _meta, args}) do
vars =
Macro.prewalk(args, fn
{:\\, _meta, [var, _default]} -> var
ast -> ast
end)
quote do
def unquote({name, [line: __ENV__.line], args})
def unquote({name, [line: __ENV__.line], vars}), do: impl().unquote(name)(unquote_splicing(vars))
end
end
end |
UPD: it didn't work |
Current iteration of I managed to fix all of my problems with decorator tho.
# lib/decorator/decorate.ex
defmacro before_compile(env) do
decorated =
env.module
|> Module.get_attribute(:decorated)
|> Enum.uniq()
|> Enum.reverse()
PS I just realised that my fix would break if function has it's caluse defined in separate places, e.g. defmodule A do
defmacro __using__(_opts) do
quote do
def f(0), do: :zero
end
end
end
defmodule B do
use Sibyl
@decorate_all trace()
use A
def f(x), do: x
end
B.f(0) #=> :zero Could be fixed later with I'm in favour of this behaviour compared to existing one, which couldn't be fixed in user code at all |
IMO we should mention this problem in readme. Unrelated, but it would be nice:
Maybe I'll implement both today. UPD
Is not so necessary, since all modules in releases are loaded at startup, thus reducing |
When including Sibyl into other
__using__/1
macros, comilation breaks in several ways:...defines defaults multiple times. Elixir allows defaults to be declared once per definition
defoverridable/1
stops working.Example:
PS
defoverridable/1
can be fixed ifuse Sibyl...
is declared after it. Perhaps decoration can be done as the last step of module compilation?PPS looks like it's Decorator bug, not Sibyl's
The text was updated successfully, but these errors were encountered: