Function-specific attribute values

Hello,

I was wondering if there was any way of defining an attribute whose value only applies to a following function definition, like @doc does. So far, all of the documentation I’ve been reading have only dealt with attributes whose values apply module-wide, and I was wondering if creating an attribute like @doc would even be possible.

Thanks in advance!

1 Like

I don’t quite follow the use case here. If you need some value specific to a function, then why not just declare the value in the function? I mean, for example, let’s say I needed a tax rate and I only wanted it visible to a particular function definition. What’s wrong with this:

def calculate_tax_rate(amount) do
  tax_rate = 1.06 #Yay Michigan!
  amount * tax_rate
end

I’m not sure how having an @tax_rate attribute (assuming it’s only used in calculate_tax_rate) would be a significant improvement. Can you detail your use case a bit more?

1 Like

There are plenty of use cases, one was already mentioned, @doc also one could think of a @deprecated <version> which wanrs when the funtion following this annotation is still in the code when we compile that module and the applications version in mix.exs is greater than or equal to <version>.

1 Like

I think you are searching for the module attribute @on_definition <module>.

After having this set, <module>.__on_definition__/6 will get called on every def, defp, defmacro, defmacrop` and maybe others.

An example head, I have floating around from experimenting with that attribute is def __on_definition__(env, kind, _name, args, _guards, _body)

As far as I remember env is the environment the def is in while kind is the keyword invoking this definition (def, defmacro etc). name is an atom containing the name of the defined item, args, guards and body are the ASTs of the respective parts of the definition. But I haven’t tested so far how it behaves when there are multi-headed-functions.

In you __on_definition__/6 there you can query your specific attribut, manipulate its value and also delete it again. Most functions useful for this are living in Module IIRC.


A small example which is meant to manipulate the content of @doc is at https://github.com/NobbZ/exygen/blob/master/lib/exygen/compiler.ex

Perhaps I’ll find time to continue after exam phase

1 Like

Oh I see–so using attributes as a decoration for a function. Ok, that’s a use case I just hadn’t considered.

Thanks to everyone for the responses! I will try the __on__definition__ solution out.

Did you find anything? I’m looking for the same thing, see this topic.