module Is::Extension

public

Turn a module into a mixin with superpowers.

Public Instance Methods

applies(force: false, &block) click to toggle source
public

Define behavior to be evaled on objects that include this extension.

# File lib/is/extension.rb, line 35
def applies(force: false, &block)
  defined_behaviors << Core::Extension::Behavior.new(force: force, &block)
end
extended(base) click to toggle source
Calls superclass method
# File lib/is/extension.rb, line 39
def extended(base)
  enforce_allowed_types(base)
  extend_defined_dependencies(base)
  extend_defined_behaviors(base)

  super
end
extends(*flags, dependencies: [], prepend: false, &block) click to toggle source
public

Define a module to be extended or included into objects that include this extension.

TODO: These flags almost need different names, since instance extensions could technically end up on a class. Name them by their intended use? Like a definition and usage lifecycle or something.

Maybe `definition` and `implementation`?

# File lib/is/extension.rb, line 23
def extends(*flags, dependencies: [], prepend: false, &block)
  dependencies.each do |dependency|
    defined_dependencies << Core::Extension::Dependency.new(*flags, dependency: dependency, prepend: prepend)
  end

  if block
    defined_dependencies << Core::Extension::Dependency.new(*flags, dependency: Module.new(&block), prepend: prepend)
  end
end
included(base) click to toggle source
Calls superclass method
# File lib/is/extension.rb, line 47
def included(base)
  enforce_allowed_types(base)
  include_defined_dependencies(base)
  include_defined_behaviors(base)

  super
end
restrict(*types) click to toggle source
public

Restrict the extension to one or more object types.

# File lib/is/extension.rb, line 12
def restrict(*types)
  allowed_types.concat(types).uniq!
end

Private Instance Methods

allowed?(object) click to toggle source
# File lib/is/extension.rb, line 67
        def allowed?(object)
  allowed_types.empty? || allowed_types.any? { |allowed_type|
    object <= allowed_type
  }
end
allowed_types() click to toggle source
# File lib/is/extension.rb, line 97
        def allowed_types
  @__allowed_types ||= []
end
allowed_types_string() click to toggle source
# File lib/is/extension.rb, line 61
        def allowed_types_string
  allowed_types.map { |allowed_type|
    "`#{allowed_type.inspect}'"
  }.join(", ")
end
defined_behaviors() click to toggle source
# File lib/is/extension.rb, line 101
        def defined_behaviors
  @__defined_behaviors ||= []
end
defined_dependencies() click to toggle source
# File lib/is/extension.rb, line 105
        def defined_dependencies
  @__defined_dependencies ||= []
end
enforce_allowed_types(object) click to toggle source
# File lib/is/extension.rb, line 55
        def enforce_allowed_types(object)
  return if allowed?(object)

  raise TypeError, "Expected `#{object}' to be a decendent of an allowed type: #{allowed_types_string}"
end
extend_defined_behaviors(object) click to toggle source
# File lib/is/extension.rb, line 73
        def extend_defined_behaviors(object)
  defined_behaviors.each do |behavior|
    behavior.apply_extend(object)
  end
end
extend_defined_dependencies(object) click to toggle source
# File lib/is/extension.rb, line 79
        def extend_defined_dependencies(object)
  defined_dependencies.each do |dependency|
    dependency.apply_extend(object)
  end
end
include_defined_behaviors(object) click to toggle source
# File lib/is/extension.rb, line 85
        def include_defined_behaviors(object)
  defined_behaviors.each do |behavior|
    behavior.apply_include(object)
  end
end
include_defined_dependencies(object) click to toggle source
# File lib/is/extension.rb, line 91
        def include_defined_dependencies(object)
  defined_dependencies.each do |dependency|
    dependency.apply_include(object)
  end
end