Feature #12737
closedModule#defined_refinements
Description
How about to provide Module#defined_refinements, which returns the refinements defined in the receiver as a Hash, as follows:
module M
refine String do
$M_String = self
end
refine Integer do
$M_Integer = self
end
end
p M.defined_refinements #=> {String => $M_String, Integer => $M_Integer}
By Module#defined_refinements
, you can activate refinements globally:
for klass, refinement in M.defined_refinements
klass.prepend(refinement)
end
Updated by shugo (Shugo Maeda) about 8 years ago
- Related to Feature #9704: Refinements as files instead of modules added
Updated by shugo (Shugo Maeda) about 3 years ago
- Status changed from Open to Assigned
Matz, can I add Module#defined_refinements?
Updated by Eregon (Benoit Daloze) about 3 years ago
- Related to Feature #14332: Module.used_refinements to list refinement modules added
Updated by Eregon (Benoit Daloze) about 3 years ago
Should the code in the description be p M.defined_refinements
?
I'm not sure to understand the use case, isn't using M
doing the same as that for
?
Updated by shugo (Shugo Maeda) about 3 years ago
Eregon (Benoit Daloze) wrote in #note-4:
Should the code in the description be
p M.defined_refinements
?
Yes.
I'm not sure to understand the use case, isn't
using M
doing the same as thatfor
?
Forget the following example. It was not a good idea.
for klass, refinement in Module.defined_refinements
klass.prepend(refinement)
end
Module#defined_refinements is a reflection API for debugging purposes.
You can get a similar result of Module.used_refinements using Module.use_modules and Module#defined_refinements except that Module.used_refinements only returns refinements defined at the time when modules are used.
Updated by Eregon (Benoit Daloze) about 3 years ago
Ah, so it's to list the refinements (instance of Refinement) under a "namespace module" like M
, without needing using
.
I'm unsure of use cases besides debugging, but I think it's useful to add.
Updated by shugo (Shugo Maeda) about 3 years ago
Considerations raised by Matz at the developers meeting on 2021-11-18:
-
Is the name defined_refinements appropriate?
other proposals:
- configured_refinements (by tenderlove)
- refinements
- consistent with Module#constants
- contained_refinements
-
Should the return value be an Array instead of a Hash?
pros:
- consistent with Module.used_refinements
cons:
- A new API like Refinement#refined_class (or target_class) is needed to know the refined class.
-
M.defined_refinements.find { |r| r.refined_class == Integer }
is longer thanM.defined_refinements[Integer]
.
Updated by Eregon (Benoit Daloze) about 3 years ago
Module#refinements seems nice and straightforward.
I think Refinement#refined_class
is useful in any case, +1 to add that.
I slightly prefer the array variant.
Since this would be mostly used for debugging, there might not be any need to filter in many cases, i.e., the Refinement#inspect output already shows the refined_class's name, so p M.refinements
seems typical usage (and the Hash for that case would just be more verbose).
Updated by shugo (Shugo Maeda) about 3 years ago
Eregon (Benoit Daloze) wrote in #note-10:
Module#refinements seems nice and straightforward.
I prefer Module#refinements too.
I slightly prefer the array variant.
Since this would be mostly used for debugging, there might not be any need to filter in many cases, i.e., the Refinement#inspect output already shows the refined_class's name, sop M.refinements
seems typical usage (and the Hash for that case would just be more verbose).
The array variant is OK for me if Refinement#refined_class will be introduced.
Another use case is testing of Refinements themselves:
m = Module.new {
refine Integer do
....
end
refine String do
...
end
}
refinements = m.refinements
assert_something ..., refinements[Integer]
assert_something ..., refinements[String]
However, I may be the only user, so it's not so important.
If there are more use cases, Module#refinement_get can be added in the future.
Updated by matz (Yukihiro Matsumoto) almost 3 years ago
OK, accepted. After 3.1, you can introduce:
- Module#refinements
- Refinment#refined_class
Matz.
Updated by shugo (Shugo Maeda) almost 3 years ago
- Assignee set to shugo (Shugo Maeda)
Updated by shugo (Shugo Maeda) almost 3 years ago
- Status changed from Assigned to Closed
Applied in changeset git|54198c7b97d3d353f7ac233e0360034b6e7b6cb6.
Add Module#refinements and Refinement#refined_class [Feature #12737]
Updated by Eregon (Benoit Daloze) over 1 year ago
Refinement#refined_class
is a bit strange given it can return a module.
How about adding Refinement#refined_module
as an alias for clarity?
Updated by shugo (Shugo Maeda) over 1 year ago
Eregon (Benoit Daloze) wrote in #note-15:
Refinement#refined_class
is a bit strange given it can return a module.
How about addingRefinement#refined_module
as an alias for clarity?
I'm for it, but it may be better to create another issue.
Updated by Eregon (Benoit Daloze) over 1 year ago
- Related to Feature #19714: Add Refinement#refined_module added