Fine Grained Mixins¶
Sapphire's fine grained mixins solve the multi-mixin problem without resorting to the static composition of Traits. In short, it allows you to selectively include, exclude or alias methods at the moment of inclusion.
Altering include¶
Whereas Ruby's include method includes all methods from a given module into a class, Sapphire alters the include method to accept a list of methods to selectively include. The following example illustrates a class that mixes in the method_a method from ModA, and the method_b method from ModB:module ModA def method_a; end def method_b; end end module ModB def method_a; end def method_b; end end # Mixin 'method_a' from ModA, and 'method_b' from ModB class ClassA include ModA, :method_a include ModB, :method_b end
Explicit exclusion¶
If a module has a large number of methods, and a programmer wants all but one or two them, the above notation quickly becomes cumbersome. Therefore, Sapphire accepts an exclude parameter, which accepts an array of method names to explicitly exclude from the mixed in module. The rest of the module's methods are included. The following example excludes method_a and method_e from being mixed into ClassA, accepting the rest of the methods:module ModA def method_a; end def method_b; end def method_c; end def method_d; end def method_e; end end # Mixin all methods except 'method_a' and 'method_e' class ClassA include ModA, :exclude => [:method_a, :method_e] end
On the fly aliasing¶
In some cases a programmer may want the functionality of a particular method from a given module, but at the same time needs to avoid a name collision. Sapphire's include method accepts the alias keyword parameter that allows you to alias a method name on the fly, including the method by the alias rather than its original name. The following example mixes in method_a from ModA into ClassA, but with the name my_method_a:
module ModA def method_a; end def method_b; end end # Mixin 'method_a' from ModA, but as 'my_method' instead. class ClassA include ModA, :alias => [:method_a, :my_method] end a = ClassA.new a.my_method # Legal
Rules¶
- You cannot both include and exclude the same method or an error is raised.
- An include without any arguments is the same as Ruby's current include mechanism.