Class: Module
- Defined in:
- lib/gems/facets-2.4.5/lib/more/facets/capsule.rb,
lib/mack-facets/extensions/module.rb,
lib/gems/extlib-0.9.8/lib/extlib/module.rb,
lib/gems/facets-2.4.5/lib/more/facets/attr.rb,
lib/gems/facets-2.4.5/lib/core/facets/metaid.rb,
lib/gems/facets-2.4.5/lib/more/facets/memoize.rb,
lib/gems/facets-2.4.5/lib/more/facets/paramix.rb,
lib/gems/facets-2.4.5/lib/more/facets/overload.rb,
lib/gems/facets-2.4.5/lib/more/facets/settings.rb,
lib/gems/facets-2.4.5/lib/core/facets/module/is.rb,
lib/gems/facets-2.4.5/lib/core/facets/module/op.rb,
lib/gems/facets-2.4.5/lib/more/facets/equatable.rb,
lib/gems/facets-2.4.5/lib/core/facets/module/can.rb,
lib/gems/facets-2.4.5/lib/more/facets/dependency.rb,
lib/gems/facets-2.4.5/lib/more/facets/annotations.rb,
lib/gems/facets-2.4.5/lib/more/facets/annotations.rb,
lib/gems/facets-2.4.5/lib/more/facets/methodspace.rb,
lib/gems/facets-2.4.5/lib/core/facets/module/class.rb,
lib/gems/facets-2.4.5/lib/more/facets/classmethods.rb,
lib/gems/facets-2.4.5/lib/core/facets/module/revise.rb,
lib/gems/facets-2.4.5/lib/core/facets/module/nesting.rb,
lib/gems/facets-2.4.5/lib/core/facets/module/pathize.rb,
lib/gems/facets-2.4.5/lib/core/facets/module/prepend.rb,
lib/gems/facets-2.4.5/lib/more/facets/1stclassmethod.rb,
lib/gems/facets-2.4.5/lib/core/facets/module/abstract.rb,
lib/gems/facets-2.4.5/lib/core/facets/module/ancestor.rb,
lib/gems/facets-2.4.5/lib/core/facets/module/basename.rb,
lib/gems/facets-2.4.5/lib/core/facets/module/conflict.rb,
lib/gems/facets-2.4.5/lib/core/facets/module/modspace.rb,
lib/gems/facets-2.4.5/lib/more/facets/class_extension.rb,
lib/gems/facets-2.4.5/lib/core/facets/module/methodize.rb,
lib/gems/facets-2.4.5/lib/core/facets/module/spacename.rb,
lib/gems/facets-2.4.5/lib/core/facets/module/module_load.rb,
lib/gems/facets-2.4.5/lib/core/facets/module/wrap_method.rb,
lib/gems/facets-2.4.5/lib/core/facets/module/rename_method.rb,
lib/gems/facets-2.4.5/lib/core/facets/comparable/comparable.rb,
lib/gems/facets-2.4.5/lib/core/facets/module/alias_accessor.rb,
lib/gems/facets-2.4.5/lib/core/facets/module/redefine_method.rb,
lib/gems/facets-2.4.5/lib/core/facets/module/redirect_method.rb,
lib/gems/facets-2.4.5/lib/core/facets/module/instance_methods.rb,
lib/gems/facets-2.4.5/lib/core/facets/module/alias_method_chain.rb,
lib/gems/facets-2.4.5/lib/core/facets/module/alias_module_function.rb,
lib/gems/facets-2.4.5/lib/core/facets/module/include_function_module.rb
Overview
It would nice if we could the following. Then the middle portion of the #Comparable method would not be needed. But I fear it might break others code.
module Comparable
def <=>(other)
comparability.each do |field|
cmp = send(field) <=> other.send(field); return cmp unless cmp == 0
end
end
end
Direct Known Subclasses
Instance Method Summary collapse
-
#*(rename_map) ⇒ Object
Rename methods.
-
#+(other) ⇒ Object
Combine modules.
-
#-(other) ⇒ Object
Subtract modules.
-
#abstract(*sym) ⇒ Object
Create an abstract method.
-
#alias_accessor!(*args) ⇒ Object
(also: #alias_switcher, #alias_toggler)
Create aliases for flag accessors.
-
#alias_method_chain(target, feature) {|aliased_target, punctuation| ... } ⇒ Object
Encapsulates the common pattern of:.
-
#alias_reader!(*args) ⇒ Object
(also: #alias_reader?, #alias_tester)
Create aliases for flag reader.
-
#alias_setter(*args) ⇒ Object
Alias an accessor.
-
#alias_validator(*args) ⇒ Object
Create aliases for validators.
-
#alias_writer!(*args) ⇒ Object
Create aliases for flag writer.
-
#all_instance_methods(include_super = true) ⇒ Object
List all instance methods, equivalent to.
-
#ancestor?(mod) ⇒ Boolean
Is a given class or module an ancestor of this class or module?.
-
#ann(ref, keys_or_class = nil, keys = nil) ⇒ Object
Set or read annotations.
-
#ann!(ref, keys_or_class = nil, keys = nil) ⇒ Object
To change an annotation’s value in place for a given class or module it first must be duplicated, otherwise the change may effect annotations in the class or module’s ancestors.
- #annotations ⇒ Object
- #append_features(mod) ⇒ Object
- #append_features_without_class_extension ⇒ Object
- #append_features_without_classmethods ⇒ Object
- #attr(*args) ⇒ Object
-
#attr_accessor!(*args) ⇒ Object
(also: #attr_switcher, #attr_toggler)
Create a toggle attribute.
-
#attr_reader!(*args) ⇒ Object
(also: #attr_reader?, #attr_tester)
Create an tester attribute.
-
#attr_setter(*args) ⇒ Object
Create an attribute method for both getting and setting an instance variable.
-
#attr_validator(*symbols, &validator) ⇒ Object
Like attr_writer, but the writer method validates the setting against the given block.
-
#attr_writer!(*args) ⇒ Object
Create a flaggable attribute.
-
#basename ⇒ Object
Returns the root name of the module/class.
-
#class_def(name, &blk) ⇒ Object
Defines an instance method within a class.
- #class_methods(&yld) ⇒ Object (also: #class_inherit)
-
#classified_attributes ⇒ Object
Return list of attributes that have a :class annotation.
-
#Comparable(*accessors) ⇒ Object
Automatically generate sorting defintions base on attribute fields.
-
#conflict?(other) ⇒ Boolean
Detect conflicts.
-
#convert_security_of_methods(old_level = :public, new_level = :protected) ⇒ Object
Bulk converts the security level of methods in this Module from one level to another.
- #define_dependency(name, *deps) ⇒ Object
- #depend(name_and_deps = nil) ⇒ Object
-
#dependencies(name, build = []) ⇒ Object
Compile list of all unique prerequisite calls.
-
#Equatable(*accessors) ⇒ Object
This function provided a “shortcut” for creating the #identity method based on given accessors and returns the Equatable module for inclusion.
- #find_const(const_name) ⇒ Object
- #heritage(ref) ⇒ Object
-
#include_as(h) ⇒ Object
Include a module via a specified space.
-
#include_safely_into(*args) ⇒ Object
Includes this module into a Class, and changes all public methods to protected.
-
#instance_method!(s) ⇒ Object
Easy access to method as objects, and they retain state!.
-
#instance_method_defined?(meth) ⇒ Boolean
Query whether a public instance method is defined for the module.
-
#integrate(mod, &block) ⇒ Object
Using integrate is just like using include except the module included is a reconstruction of the one given altered by the commands given in the block.
-
#is(*mods) ⇒ Object
alias_method :is, :include.
-
#is?(base) ⇒ Boolean
Is a given class or module an ancestor of this class or module?.
-
#memoize(*meths) ⇒ Object
Directive for making your functions faster by trading space for time.
- #method_overloads ⇒ Object
-
#method_space(name, mod = nil, &blk) ⇒ Object
Define a simple method namespace.
-
#methodize ⇒ Object
Translate a module name to a suitable method name.
-
#mixin_parameters ⇒ Object
(also: #mixin_params)
Store for parametric mixin parameters.
-
#modspace ⇒ Object
Returns the module’s container module.
-
#module_load(path) ⇒ Object
(also: #class_load)
Load file into module/class namespace.
-
#module_require(path) ⇒ Object
(also: #class_require)
Require file into module/class namespace.
-
#nesting ⇒ Object
Show a modules nesting in module namespaces.
-
#overload(name, *signiture, &block) ⇒ Object
Overload methods.
-
#pathize ⇒ Object
Converts a class name to a unix path.
-
#prepend(aspect) ⇒ Object
Prepend an
aspectmodule to a module. -
#private_conflict?(other) ⇒ Boolean
Like #conflict?, but checks only private methods.
-
#protected_conflict?(other) ⇒ Boolean
Like #conflict?, but checks only protected methods.
-
#public_conflict?(other) ⇒ Boolean
Like #conflict?, but checks only public methods.
-
#revise(&blk) ⇒ Object
(also: #revisal)
Return a new module based on another.
-
#setting(sym, options = {}) ⇒ Object
Defines a configuration setting for the enclosing class.
-
#singleton_method_defined?(meth) ⇒ Boolean
(also: #module_method_defined?)
Query whether a normal (singleton) method is defined for the module.
-
#spacename ⇒ Object
Returns the name of module’s container module.
- #try_dup ⇒ Object
-
#wrap_method(sym, &blk) ⇒ Object
(also: #wrap)
Creates a new method wrapping the previous of the same name.
Instance Method Details
#*(rename_map) ⇒ Object
Rename methods.
module A
def a; "a"; end
end
B = A * { :a => :b }
class X; include B; end
X.new.b #=> "a"
CREDIT: Thomas Sawyer
CREDIT: Robert Dober
83 84 85 86 87 88 89 90 91 92 |
# File 'lib/gems/facets-2.4.5/lib/core/facets/module/op.rb', line 83 def *(rename_map) base = self Module.new do include base rename_map.each do |from, to| alias_method to, from undef_method from end end end |
#+(other) ⇒ Object
Combine modules.
module A
def a; "a"; end
end
module B
def b; "b"; end
end
C = A + B
class X; include C; end
X.new.a #=> "a"
X.new.b #=> "b"
Note that in the old version of traits.rb we cloned modules and altered their copies. Eg.
def +(other)
mod1 = other.clone
mod2 = clone
mod1.module_eval{ include mod2 }
end
Later it was realized that this thwarted the main benefit that Ruby’s concept of modules has over traditional traits, inheritance.
CREDIT: Thomas Sawyer
CREDIT: Robert Dober
36 37 38 39 40 41 42 |
# File 'lib/gems/facets-2.4.5/lib/core/facets/module/op.rb', line 36 def +(other) base = self Module.new do include base include other end end |
#-(other) ⇒ Object
Subtract modules.
TODO: Should this use all instance_methods, not just public?
CREDIT: Thomas Sawyer
CREDIT: Robert Dober
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/gems/facets-2.4.5/lib/core/facets/module/op.rb', line 51 def -(other) case other when Array subtract = instance_methods(true) & other.collect{|m| m.to_s} when Module subtract = instance_methods(true) & other.instance_methods(true) # false? when String, Symbol subtract = instance_methods(true) & [other.to_s] end base = self Module.new do include base subtract.each{ |x| undef_method x } end end |
#abstract(*sym) ⇒ Object
Create an abstract method. If it is not overridden, it will raise a TypeError when called.
class C
abstract :a
end
c = C.new
c.a #=> Error: undefined abstraction #a
CREDIT: Trans
15 16 17 18 19 |
# File 'lib/gems/facets-2.4.5/lib/core/facets/module/abstract.rb', line 15 def abstract( *sym ) sym.each { |s| define_method( s ) { raise TypeError, "undefined abstraction ##{s}" } } end |
#alias_accessor!(*args) ⇒ Object Also known as: alias_switcher, alias_toggler
Create aliases for flag accessors.
CREDIT: Trans
117 118 119 120 121 122 123 124 |
# File 'lib/gems/facets-2.4.5/lib/more/facets/attr.rb', line 117 def alias_accessor!(*args) orig = args.last args = args - [orig] args.each do |name| alias_method("#{name}?", "#{orig}?") alias_method("#{name}!", "#{orig}!") end end |
#alias_method_chain(target, feature) {|aliased_target, punctuation| ... } ⇒ Object
Encapsulates the common pattern of:
alias_method :foo_without_feature, :foo
alias_method :foo, :foo_with_feature
With this, you simply do:
alias_method_chain :foo, :feature
And both aliases are set up for you.
Query and bang methods (foo?, foo!) keep the same punctuation:
alias_method_chain :foo?, :feature
is equivalent to
alias_method :foo_without_feature?, :foo?
alias_method :foo?, :foo_with_feature?
so you can safely chain foo, foo?, and foo! with the same feature.
CREDIT: Bitsweat
CREDIT: Rails Team
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/gems/facets-2.4.5/lib/core/facets/module/alias_method_chain.rb', line 28 def alias_method_chain(target, feature) # Strip out punctuation on predicates or bang methods since # e.g. target?_without_feature is not a valid method name. aliased_target, punctuation = target.to_s.sub(/([?!=])$/, ''), $1 yield(aliased_target, punctuation) if block_given? with_method, without_method = "#{aliased_target}_with_#{feature}#{punctuation}", "#{aliased_target}_without_#{feature}#{punctuation}" alias_method without_method, target alias_method target, with_method case when public_method_defined?(without_method) public target when protected_method_defined?(without_method) protected target when private_method_defined?(without_method) private target end end |
#alias_reader!(*args) ⇒ Object Also known as: alias_reader?, alias_tester
Create aliases for flag reader.
CREDIT: Trans
159 160 161 162 163 164 165 |
# File 'lib/gems/facets-2.4.5/lib/more/facets/attr.rb', line 159 def alias_reader!(*args) orig = args.last args = args - [orig] args.each do |name| alias_method("#{name}?", "#{orig}?") end end |
#alias_setter(*args) ⇒ Object
Alias an accessor. This create an alias for both a reader and a writer.
class X
attr_accessor :a
alias_accessor :b, :a
end
x = X.new
x.b = 1
x.a #=> 1
CREDIT: Trans
81 82 83 84 85 86 |
# File 'lib/gems/facets-2.4.5/lib/more/facets/attr.rb', line 81 def alias_setter(*args) args = args - [orig] args.each do |name| alias_method(name, orig) end end |
#alias_validator(*args) ⇒ Object
Create aliases for validators.
24 25 26 27 28 29 30 31 |
# File 'lib/gems/facets-2.4.5/lib/more/facets/attr.rb', line 24 def alias_validator(*args) orig = args.last args = args - [orig] args.each do |name| #alias_method(name, orig) alias_method("#{name}=", "#{orig}=") end end |
#alias_writer!(*args) ⇒ Object
Create aliases for flag writer.
CREDIT: Trans
200 201 202 203 204 205 206 |
# File 'lib/gems/facets-2.4.5/lib/more/facets/attr.rb', line 200 def alias_writer!(*args) orig = args.last args = args - [orig] args.each do |name| alias_method("#{name}!", "#{orig}!") end end |
#all_instance_methods(include_super = true) ⇒ Object
List all instance methods, equivalent to
public_instance_methods +
protected_instance_methods +
private_instance_methods
TODO: Better name for #all_instance_methods?
CREDIT: Trans
13 14 15 16 17 |
# File 'lib/gems/facets-2.4.5/lib/core/facets/module/instance_methods.rb', line 13 def all_instance_methods(include_super=true) public_instance_methods(include_super) + protected_instance_methods(include_super) + private_instance_methods(include_super) end |
#ancestor?(mod) ⇒ Boolean
Is a given class or module an ancestor of this class or module?
class X ; end
class Y < X ; end
X.ancestor?(Y)
11 12 13 |
# File 'lib/gems/facets-2.4.5/lib/core/facets/module/ancestor.rb', line 11 def ancestor?( mod ) ancestors.include? mod end |
#ann(ref, keys_or_class = nil, keys = nil) ⇒ Object
Set or read annotations.
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/gems/facets-2.4.5/lib/more/facets/annotations.rb', line 123 def ann( ref, keys_or_class=nil, keys=nil ) return heritage(ref) unless keys_or_class or keys if Class === keys_or_class keys ||= {} keys[:class] = keys_or_class else keys = keys_or_class end if Hash === keys ref = ref.to_sym annotations[ref] ||= {} annotations[ref].update(keys.rekey) else key = keys.to_sym heritage(ref)[key] end end |
#ann!(ref, keys_or_class = nil, keys = nil) ⇒ Object
To change an annotation’s value in place for a given class or module it first must be duplicated, otherwise the change may effect annotations in the class or module’s ancestors.
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 |
# File 'lib/gems/facets-2.4.5/lib/more/facets/annotations.rb', line 147 def ann!( ref, keys_or_class=nil, keys=nil ) #return heritage(ref) unless keys_or_class or keys return annotations[ref] unless keys_or_class or keys if Class === keys_or_class keys ||= {} keys[:class] = keys_or_class else keys = keys_or_class end if Hash === keys ref = ref.to_sym annotations[ref] ||= {} annotations[ref].update(keys.rekey) else key = keys.to_sym annotations[ref][key] = heritage(ref)[key].dup end end |
#annotations ⇒ Object
108 109 110 111 |
# File 'lib/gems/facets-2.4.5/lib/more/facets/annotations.rb', line 108 def annotations #$annotations[self] @annotations ||= {} end |
#append_features(mod) ⇒ Object
163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 |
# File 'lib/gems/facets-2.4.5/lib/more/facets/classmethods.rb', line 163 def append_features( base ) result = append_features_without_classmethods( base ) if const_defined?( :ClassMethods ) base.extend( self::ClassMethods ) unless base.is_a?( Class ) unless base.const_defined?( :ClassMethods ) base.const_set( :ClassMethods, Module.new ) end my = self base::ClassMethods.class_eval do include my::ClassMethods end end end result end |
#append_features_without_class_extension ⇒ Object
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/gems/facets-2.4.5/lib/more/facets/class_extension.rb', line 54 def append_features( base ) result = append_features_without_classmethods( base ) if const_defined?( :ClassMethods ) base.extend( self::ClassMethods ) unless base.is_a?( Class ) unless base.const_defined?( :ClassMethods ) base.const_set( :ClassMethods, Module.new ) end my = self base::ClassMethods.class_eval do include my::ClassMethods end end end result end |
#append_features_without_classmethods ⇒ Object
161 |
# File 'lib/gems/facets-2.4.5/lib/more/facets/classmethods.rb', line 161 alias_method :append_features_without_classmethods, :append_features |
#attr(*args) ⇒ Object
222 223 224 225 226 227 228 229 230 231 232 233 234 |
# File 'lib/gems/facets-2.4.5/lib/more/facets/annotations.rb', line 222 def attr( *args ) args.flatten! case args.last when TrueClass args.pop attr_accessor( *args ) when FalseClass args.pop attr_reader( *args ) else attr_reader( *args ) end end |
#attr_accessor!(*args) ⇒ Object Also known as: attr_switcher, attr_toggler
Create a toggle attribute. This creates two methods for each given name. One is a form of tester and the other is used to toggle the value.
attr_accessor! :a
is equivalent to
def a?
@a
end
def a!(value=true)
@a = value
self
end
CREDIT: Trans
107 108 109 |
# File 'lib/gems/facets-2.4.5/lib/more/facets/attr.rb', line 107 def attr_accessor!(*args) attr_reader!(*args) + attr_writer!(*args) end |
#attr_reader!(*args) ⇒ Object Also known as: attr_reader?, attr_tester
Create an tester attribute. This creates a single method used to test the attribute for truth.
attr_reader! :a
is equivalent to
def a?
@a ? true : @a
end
139 140 141 142 143 144 145 146 147 148 149 150 151 |
# File 'lib/gems/facets-2.4.5/lib/more/facets/attr.rb', line 139 def attr_reader!(*args) code, made = '', [] args.each do |a| code << %{ def #{a}?(truth=nil) @#{a} ? truth || @#{a} : @#{a} end } made << "#{a}?".to_sym end module_eval code made end |
#attr_setter(*args) ⇒ Object
Create an attribute method for both getting and setting an instance variable.
attr_setter :a
_is equivalent to_
def a(*args)
if args.size > 0
@a = args[0]
self
else
@a
end
end
CREDIT: Trans
53 54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/gems/facets-2.4.5/lib/more/facets/attr.rb', line 53 def attr_setter(*args) code, made = '', [] args.each do |a| code << %{ def #{a}(*args) args.size > 0 ? ( @#{a}=args[0] ; self ) : @#{a} end } made << "#{a}".to_sym end module_eval code made end |
#attr_validator(*symbols, &validator) ⇒ Object
Like attr_writer, but the writer method validates the setting against the given block.
CREDIT: ?
8 9 10 11 12 13 14 15 16 17 18 19 20 |
# File 'lib/gems/facets-2.4.5/lib/more/facets/attr.rb', line 8 def attr_validator(*symbols, &validator) made = [] symbols.each do |symbol| define_method "#{symbol}=" do |val| unless validator.call(val) raise ArgumentError, "Invalid value provided for #{symbol}" end instance_variable_set("@#{symbol}", val) end made << "#{symbol}=".to_sym end made end |
#attr_writer!(*args) ⇒ Object
Create a flaggable attribute. This creates a single methods used to set an attribute to “true”.
attr_writer! :a
is equivalent to
def a!(value=true)
@a = value
self
end
181 182 183 184 185 186 187 188 189 190 191 192 193 194 |
# File 'lib/gems/facets-2.4.5/lib/more/facets/attr.rb', line 181 def attr_writer!(*args) code, made = '', [] args.each do |a| code << %{ def #{a}!(value=true) @#{a} = value self end } made << "#{a}!".to_sym end module_eval code made end |
#basename ⇒ Object
Returns the root name of the module/class.
module Example
class Demo
end
end
Demo.name #=> "Example::Demo"
Demo.basename #=> "Demo"
For anonymous modules this will provide a basename based on Module#inspect.
m = Module.new
m.inspect #=> "#<Module:0xb7bb0434>"
m.basename #=> "Module_0xb7bb0434"
CREDIT: Trans
22 23 24 25 26 27 28 |
# File 'lib/gems/facets-2.4.5/lib/core/facets/module/basename.rb', line 22 def basename if name and not name.empty? name.gsub(/^.*::/, '') else nil #inspect.gsub('#<','').gsub('>','').sub(':', '_') end end |
#class_def(name, &blk) ⇒ Object
Defines an instance method within a class.
CREDIT: WhyTheLuckyStiff
82 83 84 |
# File 'lib/gems/facets-2.4.5/lib/core/facets/metaid.rb', line 82 def class_def name, &blk class_eval { define_method name, &blk } end |
#class_methods(&yld) ⇒ Object Also known as: class_inherit
180 181 182 183 184 185 186 187 188 |
# File 'lib/gems/facets-2.4.5/lib/more/facets/classmethods.rb', line 180 def class_methods( &yld ) if const_defined?( :ClassMethods ) self::ClassMethods.class_eval( &yld ) else self.const_set( :ClassMethods, Module.new( &yld ) ) end extend( self::ClassMethods ) self::ClassMethods end |
#classified_attributes ⇒ Object
Return list of attributes that have a :class annotation.
class MyClass
attr_accessor :test
attr_accessor :name, String, :doc => 'Hello'
attr_accessor :age, Fixnum
end
MyClass.instance_attributes # => [:test, :name, :age, :body]
MyClass.classified_attributes # => [:name, :age]
295 296 297 298 299 |
# File 'lib/gems/facets-2.4.5/lib/more/facets/annotations.rb', line 295 def classified_attributes instance_attributes.find_all do |a| self.ann(a, :class) end end |
#Comparable(*accessors) ⇒ Object
Automatically generate sorting defintions base on attribute fields.
include SortOn(:a, :b)
is equivalent to including a module containing:
def <=>(other)
cmp = self.a <=> other.a; return cmp unless cmp == 0
cmp = self.b <=> other.b; return cmp unless cmp == 0
0
end
28 29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/gems/facets-2.4.5/lib/core/facets/comparable/comparable.rb', line 28 def Comparable(*accessors) define_method(:comparability){ accessors } code = %{ def <=>(other) comparability.each do |a| cmp = (send(a) <=> other.send(a)); return cmp unless cmp == 0 end end } module_eval code return Comparable end |
#conflict?(other) ⇒ Boolean
Detect conflicts.
module A
def c; end
end
module B
def c; end
end
A.conflict?(B) #=> ["c"]
TODO: All instance methods, or just public?
CREDIT: Thomas Sawyer
CREDIT: Robert Dober
21 22 23 24 25 26 27 28 29 30 31 |
# File 'lib/gems/facets-2.4.5/lib/core/facets/module/conflict.rb', line 21 def conflict?(other) common_ancestor = (ancestors & other.ancestors).first c = [] c += (public_instance_methods(true) & other.public_instance_methods(true)) c += (private_instance_methods(true) & other.private_instance_methods(true)) c += (protected_instance_methods(true) & other.protected_instance_methods(true)) c -= common_ancestor.public_instance_methods(true) c -= common_ancestor.private_instance_methods(true) c -= common_ancestor.protected_instance_methods(true) c.empty? ? false : c end |
#convert_security_of_methods(old_level = :public, new_level = :protected) ⇒ Object
Bulk converts the security level of methods in this Module from one level to another.
4 5 6 7 |
# File 'lib/mack-facets/extensions/module.rb', line 4 def convert_security_of_methods(old_level = :public, new_level = :protected) eval("#{old_level}_instance_methods").each{ |meth| self.send(new_level, meth) } self end |
#define_dependency(name, *deps) ⇒ Object
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/gems/facets-2.4.5/lib/more/facets/dependency.rb', line 120 def define_dependency( name, *deps ) @dependency ||= {} if @dependency[name.to_sym] @dependency[name.to_sym] = deps else @dependency[name.to_sym] = deps deplist = lambda{ dependencies(name) } alias_method("#{name}:execute",name) define_method(name) do |*a| # run dependencies deplist.call.each do |d| if respond_to?("#{d}:execute") send("#{d}:execute",*a) #,&b) else send(d,*a) #,&b) end end # run core method send("#{name}:execute",*a) #,&b) end end end |
#depend(name_and_deps = nil) ⇒ Object
90 91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/gems/facets-2.4.5/lib/more/facets/dependency.rb', line 90 def depend( name_and_deps=nil ) if Hash === name_and_deps name_and_deps.to_h.each do |name, deps| deps = [deps].flatten define_dependency(name, *deps) end elsif name_and_deps @dependency ||= {} @dependency[name_and_deps.to_sym] else @dependency ||= {} end end |
#dependencies(name, build = []) ⇒ Object
Compile list of all unique prerequisite calls.
106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/gems/facets-2.4.5/lib/more/facets/dependency.rb', line 106 def dependencies(name, build=[]) @dependency ||= {} deps = @dependency[name.to_sym] return build unless deps deps.each do |dep| build.unshift(dep) dependencies(dep,build) end build.uniq! build end |
#Equatable(*accessors) ⇒ Object
This function provided a “shortcut” for creating the #identity method based on given accessors and returns the Equatable module for inclusion.
include Equatable(:a, :b)
is equivalent to including a module containing:
def ==(other)
self.a == other.a && self.b == other.b
end
def eql?(other)
self.a.eql?(other.a) && self.b.eql?(other.b)
end
def hash()
self.a.hash ^ self.b.hash
end
115 116 117 |
# File 'lib/gems/facets-2.4.5/lib/more/facets/equatable.rb', line 115 def Equatable(*accessors) Equatable.identify(self, *accessors) end |
#find_const(const_name) ⇒ Object
2 3 4 5 6 7 8 |
# File 'lib/gems/extlib-0.9.8/lib/extlib/module.rb', line 2 def find_const(const_name) if const_name[0..1] == '::' Object.find_const(const_name[2..-1]) else nested_const_lookup(const_name) end end |
#heritage(ref) ⇒ Object
113 114 115 116 117 118 119 |
# File 'lib/gems/facets-2.4.5/lib/more/facets/annotations.rb', line 113 def heritage(ref) ref = ref.to_sym ancestors.inject({}) { |memo, ancestor| ancestor.annotations[ref] ||= {} ancestor.annotations[ref] + memo } end |
#include_as(h) ⇒ Object
Include a module via a specified space.
module T
def t ; "HERE" ; end
end
class X
include_as :test => T
def t ; test.t ; end
end
X.new.t #=> "HERE"
103 104 105 |
# File 'lib/gems/facets-2.4.5/lib/more/facets/methodspace.rb', line 103 def include_as(h) h.each{ |name, mod| method_space(name, mod) } end |
#include_safely_into(*args) ⇒ Object
Includes this module into a Class, and changes all public methods to protected.
Examples:
module MyCoolUtils
def some_meth
"hi"
end
self.include_safely_into(FooController)
end
or:
MyCoolUtils.include_safely_into(FooController, SomeOtherClass)
20 21 22 23 24 25 26 27 |
# File 'lib/mack-facets/extensions/module.rb', line 20 def include_safely_into(*args) [args].flatten.each do |a| if a.is_a?(String) || a.is_a?(Symbol) a = a.to_s.constantize end a.send(:include, self.convert_security_of_methods) end end |
#instance_method!(s) ⇒ Object
Easy access to method as objects, and they retain state!
module K
def hello
puts "Hello World!"
end
end
p K.instance_method!(:hello) #=> <UnboundMethod: #hello>
NOTE: This is limited to the scope of the current module/class.
134 135 136 137 |
# File 'lib/gems/facets-2.4.5/lib/more/facets/1stclassmethod.rb', line 134 def instance_method!(s) #( @@__instance_methods__ ||= {} )[s] ||= instance_method(s) # TODO when fixed ( @__instance_methods__ ||= {} )[s] ||= instance_method(s) end |
#instance_method_defined?(meth) ⇒ Boolean
Query whether a public instance method is defined for the module.
CREDIT: Gavin Sinclair
CREDIT: Noah Gibbs
24 25 26 |
# File 'lib/gems/facets-2.4.5/lib/core/facets/module/instance_methods.rb', line 24 def instance_method_defined?(meth) instance_methods(true).find{ |m| m == meth.to_s } end |
#integrate(mod, &block) ⇒ Object
Using integrate is just like using include except the module included is a reconstruction of the one given altered by the commands given in the block.
Convenient commands available are: #rename, #redef, #remove, #nodef and #wrap. But any module method can be used.
module W
def q ; "q" ; end
def y ; "y" ; end
end
class X
integrate W do
nodef :y
end
end
x = X.new
x.q #=> "q"
x.y #=> missing method error
This is like #revisal, but #revisal only returns the reconstructred module. It does not include it.
CREDIT: Trans
51 52 53 54 55 56 |
# File 'lib/gems/facets-2.4.5/lib/core/facets/module/revise.rb', line 51 def integrate(mod, &block) #include mod.revisal( &blk ) m = Module.new{ include mod } m.class_eval(&block) include m end |
#is(*mods) ⇒ Object
alias_method :is, :include
27 28 29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/gems/facets-2.4.5/lib/core/facets/module/is.rb', line 27 def is(*mods) mods.each do |mod| if mod.const_defined?(:Self) extend mod::Self # pass it along if module if instance_of?(Module) const_set(:Self, Module.new) unless const_defined?(:Self) const_get(:Self).send(:include, mod::Self) end end end include(*mods) end |
#is?(base) ⇒ Boolean
Is a given class or module an ancestor of this class or module?
class X ; end
class Y < X ; end
Y.is?(X) #=> true
CREDIT: Trans
13 14 15 |
# File 'lib/gems/facets-2.4.5/lib/core/facets/module/is.rb', line 13 def is?(base) ancestors.slice(1..-1).include?(base) end |
#memoize(*meths) ⇒ Object
Directive for making your functions faster by trading space for time. When you “memoize” a method/function its results are cached so that later calls with the same arguments returns results in the cache instead of recalculating them.
class T
def initialize(a)
@a = a
end
def a
"#{@a ^ 3 + 4}"
end
memoize :a
end
t = T.new
t.a.__id__ == t.a.__id__ #=> true
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/gems/facets-2.4.5/lib/more/facets/memoize.rb', line 61 def memoize(*meths) @_MEMOIZE_CACHE ||= Hash.new meths.each do |meth| mc = @_MEMOIZE_CACHE[meth] = Hash.new old = instance_method(meth) new = proc do |*args| if mc.has_key? args mc[args] else mc[args] = old.bind(self).call(*args) end end send(:define_method, meth, &new) end end |
#method_overloads ⇒ Object
25 26 27 |
# File 'lib/gems/facets-2.4.5/lib/more/facets/overload.rb', line 25 def method_overloads @method_overloads ||= {} end |
#method_space(name, mod = nil, &blk) ⇒ Object
Define a simple method namespace.
class A
attr_writer :x
method_space :inside do
def x; @x; end
end
end
a = A.new
a.x = 10
a.inside.x #=> 10
a.x # no method error
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/gems/facets-2.4.5/lib/more/facets/methodspace.rb', line 48 def method_space(name, mod=nil, &blk) # If block is given then create a module, otherwise # get the name of the module. if block_given? name = name.to_s raise ArgumentError if mod mod = Module.new(&blk) else if Module === name mod = name name = mod.basename.downcase end mod = mod.dup end # Include the module. This is neccessary, otherwise # Ruby won't let us bind the instance methods. include mod # Save the instance methods of the module and # replace them with a "transparent" version. methods = {} mod.instance_methods(false).each do |m| methods[m.to_sym] = mod.instance_method(m) mod.instance_eval do define_method(m) do super end end end # Add a method for the namespace that delegates # via the Functor to the saved instance methods. define_method(name) do mtab = methods Functor.new do |op, *args| mtab[op].bind(self).call(*args) end end end |
#methodize ⇒ Object
Translate a module name to a suitable method name.
My::CoolClass.methodize => "my__cool_class"
9 10 11 |
# File 'lib/gems/facets-2.4.5/lib/core/facets/module/methodize.rb', line 9 def methodize name.methodize end |
#mixin_parameters ⇒ Object Also known as: mixin_params
Store for parametric mixin parameters.
Returns a hash, the keys of which are the parametric mixin module and the values are the parameters associacted with this module/class.
class C
include P(:x=>1)
end
C.mixin_parameters[P] #=> {:x=>1}
196 197 198 |
# File 'lib/gems/facets-2.4.5/lib/more/facets/paramix.rb', line 196 def mixin_parameters @mixin_parameters ||= {} end |
#modspace ⇒ Object
Returns the module’s container module.
module Example
class Demo
end
end
Example::Demo.modspace #=> Example
See also Module#basename.
CREDIT: Trans
16 17 18 19 |
# File 'lib/gems/facets-2.4.5/lib/core/facets/module/modspace.rb', line 16 def modspace space = name[ 0...(name.rindex( '::' ) || 0)] space.empty? ? Object : eval(space) end |
#module_load(path) ⇒ Object Also known as: class_load
Load file into module/class namespace.
CREDIT: Trans
9 10 11 12 13 14 15 16 17 18 19 20 21 |
# File 'lib/gems/facets-2.4.5/lib/core/facets/module/module_load.rb', line 9 def module_load( path ) if path =~ /^[\/~.]/ file = File.(path) else $LOAD_PATH.each do |lp| file = File.join(lp,path) break if File.exist?(file) file = nil end end raise LoadError, "no such file to load -- #{path}" unless file module_eval(File.read(file)) end |
#module_require(path) ⇒ Object Also known as: class_require
Require file into module/class namespace.
CREDIT: Trans
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/gems/facets-2.4.5/lib/core/facets/module/module_load.rb', line 27 def module_require( path ) if path =~ /^[\/~.]/ file = File.(path) else $LOAD_PATH.each do |lp| file = File.join(lp,path) break if File.exist?(file) file += '.rb' break if File.exist?(file) file = nil end end raise LoadError, "no such file to load -- #{path}" unless file @loaded ||= {} if @loaded.key?(file) false else @loaded[file] = true script = File.read(file) module_eval(script) true end end |
#nesting ⇒ Object
Show a modules nesting in module namespaces.
A::B::C.nesting #=> [ A, A::B ]
CREDIT: Trans
9 10 11 12 13 14 15 |
# File 'lib/gems/facets-2.4.5/lib/core/facets/module/nesting.rb', line 9 def nesting n = [] name.split(/::/).inject(self) do |mod, name| c = mod.const_get(name) ; n << c ; c end return n end |
#overload(name, *signiture, &block) ⇒ Object
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/gems/facets-2.4.5/lib/more/facets/overload.rb', line 45 def overload( name, *signiture, &block ) raise ArgumentError unless signiture.all?{|s| s.instance_of?(Class)} name = name.to_sym if method_overloads.key?( name ) method_overloads[name][signiture] = block else method_overloads[name] = {} method_overloads[name][signiture] = block if method_defined?( name ) #method_overloads[name][nil] = instance_method( name ) #true alias_method( "#{name}Generic", name ) has_generic = true else has_generic = false end define_method( name ) do |*args| ovr = self.class.method_overloads["#{name}".to_sym] sig = args.collect{ |a| a.class } hit = nil faces = ovr.keys #.sort { |a,b| b.size <=> a.size } faces.each do |cmp| next unless cmp.size == sig.size if (0...cmp.size).all?{ |i| cmp[i] >= sig[i] } break hit = cmp end end if hit ovr[hit].call(*args) else if has_generic #ovr[nil] send( "#{name}Generic", *args ) #ovr[nil].bind(self).call(*args) else raise NoMethodError end end end end end |
#pathize ⇒ Object
Converts a class name to a unix path
Examples
CoolClass.pathize #=> "cool_class"
My::CoolClass.pathize #=> "my/cool_class"
11 12 13 14 15 16 17 18 19 |
# File 'lib/gems/facets-2.4.5/lib/core/facets/module/pathize.rb', line 11 def pathize name.pathize #to_s. # gsub(/::/, '/'). # gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2'). # gsub(/([a-z\d])([A-Z])/,'\1_\2'). # tr("-", "_"). # downcase end |
#prepend(aspect) ⇒ Object
Prepend an aspect module to a module. This only works at the module level.
module X
def x; "x"; end
end
module U
def x; '{' + super + '}'; end
end
X.prepend U
X.x # => "{x}"
CREDIT Trans
20 21 22 23 |
# File 'lib/gems/facets-2.4.5/lib/core/facets/module/prepend.rb', line 20 def prepend(aspect) aspect.__send__(:include, self) extend aspect end |
#private_conflict?(other) ⇒ Boolean
Like #conflict?, but checks only private methods.
47 48 49 50 51 52 |
# File 'lib/gems/facets-2.4.5/lib/core/facets/module/conflict.rb', line 47 def private_conflict?(other) common_ancestor = (ancestors & other.ancestors).first c = private_instance_methods(true) & other.private_instance_methods(true) c -= common_ancestor.private_instance_methods(true) c.empty? ? false : c end |
#protected_conflict?(other) ⇒ Boolean
Like #conflict?, but checks only protected methods.
55 56 57 58 59 60 |
# File 'lib/gems/facets-2.4.5/lib/core/facets/module/conflict.rb', line 55 def protected_conflict?(other) common_ancestor = (ancestors & other.ancestors).first c = protected_instance_methods(true) & other.protected_instance_methods(true) c -= common_ancestor.protected_instance_methods(true) c.empty? ? false : c end |
#public_conflict?(other) ⇒ Boolean
Like #conflict?, but checks only public methods.
39 40 41 42 43 44 |
# File 'lib/gems/facets-2.4.5/lib/core/facets/module/conflict.rb', line 39 def public_conflict?(other) common_ancestor = (ancestors & other.ancestors).first c = public_instance_methods(true) & other.public_instance_methods(true) c -= common_ancestor.public_instance_methods(true) c.empty? ? false : c end |
#revise(&blk) ⇒ Object Also known as: revisal
Return a new module based on another. This includes the original module into the new one.
CREDIT: Trans
13 14 15 16 17 18 |
# File 'lib/gems/facets-2.4.5/lib/core/facets/module/revise.rb', line 13 def revise(&blk) base = self nm = Module.new{ include base } nm.class_eval(&blk) nm end |
#setting(sym, options = {}) ⇒ Object
Defines a configuration setting for the enclosing class.
Example
class Compiler
setting :template_root, :default => 'src/template', :doc => 'The template root dir'
end
233 234 235 236 237 238 239 240 241 242 243 244 245 |
# File 'lib/gems/facets-2.4.5/lib/more/facets/settings.rb', line 233 def setting(sym, = {}) Settings.add_setting(self, sym, ) module_eval %{ def self.#{sym} Settings[#{self}][:#{sym}].value end def self.#{sym}=(obj) Settings.setting #{self}, :#{sym}, :value => obj end } end |
#singleton_method_defined?(meth) ⇒ Boolean Also known as: module_method_defined?
Query whether a normal (singleton) method is defined for the module.
CREDIT: Gavin Sinclair
CREDIT: Noah Gibbs
33 34 35 |
# File 'lib/gems/facets-2.4.5/lib/core/facets/module/instance_methods.rb', line 33 def singleton_method_defined?(meth) singleton_methods(true).find{ |m| m == meth.to_s } end |
#spacename ⇒ Object
Returns the name of module’s container module.
module Example
class Demo
end
end
Demo.name #=> "Example::Demo"
Demo.spacename #=> "Example"
This used to be called dirname.
See also Module#basename.
CREDIT: Trans
19 20 21 22 |
# File 'lib/gems/facets-2.4.5/lib/core/facets/module/spacename.rb', line 19 def spacename name[0...(name.rindex('::') || 0)] #name.gsub(/::[^:]*$/, '') end |
#try_dup ⇒ Object
10 11 12 |
# File 'lib/gems/extlib-0.9.8/lib/extlib/module.rb', line 10 def try_dup self end |
#wrap_method(sym, &blk) ⇒ Object Also known as: wrap
Creates a new method wrapping the previous of the same name. Reference to the old method is passed into the new definition block as the first parameter.
wrap_method( sym ) { |old_meth, *args|
old_meth.call
...
}
Keep in mind that this can not be used to wrap methods that take a block.
CREDIT: Trans
20 21 22 23 |
# File 'lib/gems/facets-2.4.5/lib/core/facets/module/wrap_method.rb', line 20 def wrap_method( sym, &blk ) old = instance_method(sym) define_method(sym) { |*args| blk.call(old.bind(self), *args) } end |