[Proposal] Module.attribute_registered?/3 or Add Module.has_attribute?/3

40 views
Skip to first unread message

Allen Madsen

unread,
Jul 1, 2019, 11:42:28 PM7/1/19
to elixir-lang-core
In working with the ExUnit code, there are at least two places where I think being able to introspect on module attributes would be useful.

One is here. In this code it would be useful to know if a module attribute has been set already. This code checks to see if it has a value. However, if a user set the value to `nil`, this code wouldn't be able to tell.

Another situation it would be useful, is in this PR: https://github.com/elixir-lang/elixir/pull/9181. Specifically, this check, where it would also be useful to know if the attribute is registered with accumulate or not.

So, the proposal is an API something like this:

defmodule X do
  Module.register_attribute(__MODULE__, :foo, accumulate: true)
  @bar true
 
  Module.attribute_registered?(__MODULE__, :foo) #=> true
  Module.attribute_registered?(__MODULE__, :foo, accumulate: true) #=> true
  Module.attribute_registered?(__MODULE__, :foo, persist: true) #=> false

  Module.attribute_registered?(__MODULE__, :bar) #=> true
  Module.attribute_registered?(__MODULE__, :bar, accumulate: true) #=> false

  Module.attribute_registered?(__MODULE__, :baz) #=> false
end

The third argument would be a subset match of the options. 

Thoughts?

José Valim

unread,
Jul 2, 2019, 1:24:18 AM7/2/19
to elixir-l...@googlegroups.com
Thanks for the proposal.

I like has_attribute?. I prefer it over attribute_registered? because what would happen if you set an attribute without registered it? Should it return false for attribute_registetered? So has_attribute? is less ambiguous, although I would only support has_attribute?/2 for now.

Notice in order to implement this, you will have to change register_attribute to store something when called without the :persist or :accumulate. But it should be a matter of adding an else here: https://github.com/elixir-lang/elixir/blob/master/lib/elixir/lib/module.ex#L1308-L1311

Something like:

else
  :ets.insert_new(set, {attribute, nil, nil})
end

We need to document that once an attribute has been registered to accumulate or persist, it can't be done undone unless the attribute is deleted.

José Valim
Skype: jv.ptec
Founder and Director of R&D


--
You received this message because you are subscribed to the Google Groups "elixir-lang-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-co...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-core/39c87e02-8ed2-49ed-9754-d0e8f0bafd7e%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Allen Madsen

unread,
Jul 2, 2019, 8:43:16 AM7/2/19
to elixir-l...@googlegroups.com
> We need to document that once an attribute has been registered to accumulate or persist, it can't be done undone unless the attribute is deleted.

How is it undone today?

José Valim

unread,
Jul 2, 2019, 10:33:05 AM7/2/19
to elixir-l...@googlegroups.com
It can’t be undone today either. This was just a general note. It probably belongs to a separate PR.
--
Reply all
Reply to author
Forward
0 new messages