Module: RakeCommander::Base::ClassHelpers

Included in:
ClassAutoLoader, Option
Defined in:
lib/rake-commander/base/class_helpers.rb

Constant Summary collapse

NOT_USED =
:not_used!

Instance Method Summary collapse

Instance Method Details

#class_resolver(name, klass) ⇒ Object

Defines a class and instance method for lazy resolving a class.



22
23
24
25
# File 'lib/rake-commander/base/class_helpers.rb', line 22

def class_resolver(name, klass)
  define_singleton_method(name) { resolve_class(klass) }
  define_method(name) { self.class.resolve_class(klass) }
end

#descendants(parent_class: self, direct: false, scope: nil) ⇒ Arrary<Class>

Finds all child classes of the current class.

Parameters:

  • parent_class (Class) (defaults to: self)

    the parent class we want to find children of.

  • direct (Boolean) (defaults to: false)

    it will only include direct child classes.

  • scope (nil, Array) (defaults to: nil)

    to only look for descendants among the ones in scope.

Returns:

  • (Arrary<Class>)

    the child classes in hierarchy order.



104
105
106
107
108
109
110
111
112
113
# File 'lib/rake-commander/base/class_helpers.rb', line 104

def descendants(parent_class: self, direct: false, scope: nil)
  scope ||= ObjectSpace.each_object(::Class)
  return [] if scope.empty?
  siblings = scope.select {|klass| klass < parent_class}
  siblings = sort_classes(*siblings)
  return siblings unless direct
  siblings.reject! do |si|
    siblings.any? {|s| si < s}
  end
end

#descendants?(parent_class: self, direct: false) ⇒ Boolean

Returns true if the current class has child classes, and false otherwise.

Parameters:

  • parent_class (Class) (defaults to: self)

    the parent class we want to find children of.

  • direct (Boolean) (defaults to: false)

    it will only include direct child classes.

Returns:

  • (Boolean)

    true if the current class has child classes, and false otherwise.



118
119
120
# File 'lib/rake-commander/base/class_helpers.rb', line 118

def descendants?(parent_class: self, direct: false)
  !descendants(parent_class: parent_class, direct: direct).empty?
end

#new_class(name = "Child#{uid}", inherits: self, namespace: inherits) {|child_class| ... } ⇒ Class

If the class for name exists, it returns it. Otherwise it generates it.

Parameters:

  • name (String, Symbol) (defaults to: "Child#{uid}")

    the name of the new class

  • inherits (Class) (defaults to: self)

    the parent class to inherit from

  • namespace (Class, String) (defaults to: inherits)

    an existing constant (class or module) the new class will be namespaced on

Yields:

  • (child_class)

    configure the new class

Yield Parameters:

  • child_class (Class)

    the new class

Returns:

  • (Class)

    the new generated class



75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/rake-commander/base/class_helpers.rb', line 75

def new_class(name = "Child#{uid}", inherits: self, namespace: inherits)
  name            = name.to_s.to_sym.freeze
  class_name      = to_constant(name)

  unless target_class = resolve_class("#{namespace}::#{class_name}", exception: false)
    target_class = Class.new(inherits)
    Kernel.const_get(namespace.to_s).const_set class_name, target_class
  end

  target_class.tap do |klass|
    yield(klass) if block_given?
  end
end

#redef_without_warning(const, value) ⇒ Object

Redefines constant const with value without triggering a warning.



16
17
18
19
# File 'lib/rake-commander/base/class_helpers.rb', line 16

def redef_without_warning(const, value)
  self.class.send(:remove_const, const) if self.class.const_defined?(const)
  self.class.const_set(const, value)
end

#resolve_class(klass, source_class: self, exception: true) ⇒ Class

Note:

it caches the resolved klasses

Class resolver

Parameters:

  • klass (Class, String, Symbol)

    the class to resolve

  • source_class (Class) (defaults to: self)

    when the reference to klass belongs to a different inheritance chain.

  • exception (Boolean) (defaults to: true)

    if it should raise exception when could not resolve

Returns:

  • (Class)

    the Class constant

Raises:

  • (Exception)

    when could not resolve if exception is true



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/rake-commander/base/class_helpers.rb', line 34

def resolve_class(klass, source_class: self, exception: true)
  @resolved ||= {}
  @resolved[klass] ||=
    case klass
    when Class
      klass
    when String
      begin
        Kernel.const_get(klass)
      rescue NameError
        raise if exception
      end
    when Symbol
      source_class.resolve_class(source_class.send(klass))
    when Hash
      referrer, referred = klass.first
      resolve_class(referred, source_class: referrer, exception: exception)
    else
      raise "Unknown class: #{klass}" if exception
    end
end

#sort_classes(*klasses) ⇒ Arrary<Class>

Returns the classes in hierarchy order.

Parameters:

  • klasses (Arrary<Class>)

    the classes to sort.

Returns:

  • (Arrary<Class>)

    the classes in hierarchy order.



91
92
93
94
95
96
97
# File 'lib/rake-commander/base/class_helpers.rb', line 91

def sort_classes(*klasses)
  klasses.sort do |k_1, k_2|
    next -1 if k_2 < k_1
    next  1 if k_1 < k_2
    0
  end
end

#to_constant(key) ⇒ String

Note:

it removes namespace syntax ::

Helper to normalize key into a correct ruby constant name

Parameters:

  • key (String, Symbol)

    to be normalized

Returns:

  • (String)

    a correct constant name



60
61
62
63
64
65
66
# File 'lib/rake-commander/base/class_helpers.rb', line 60

def to_constant(key)
  key.to_s.strip.split(/::/).compact.map do |str|
    str.slice(0).upcase + str.slice(1..-1)
  end.join("").split(/[-_ :]+/i).compact.map do |str|
    str.slice(0).upcase + str.slice(1..-1)
  end.join("")
end

#used_param?(val) ⇒ Boolean

Note:

to effectivelly use this helper, you should initialize your target paramters with the constant NOT_USED

Helper to determine if a paramter has been used

Parameters:

  • val

    [] the value of the paramter

Returns:

  • (Boolean)

    true if value other than NOT_USED, false otherwise



11
12
13
# File 'lib/rake-commander/base/class_helpers.rb', line 11

def used_param?(val)
  val != NOT_USED
end