Module: DiverDown::Helper

Defined in:
lib/diver_down/helper.rb

Constant Summary collapse

CLASS_NAME_QUERY =
Module.method(:name).unbind.freeze

Class Method Summary collapse

Class Method Details

.class?(obj) ⇒ Boolean

Parameters:

  • obj (Object)

Returns:

  • (Boolean)


60
61
62
# File 'lib/diver_down/helper.rb', line 60

def self.class?(obj)
  Class === obj
end

.constantize(str) ⇒ Module

Parameters:

  • str (String)

Returns:

  • (Module)


66
67
68
# File 'lib/diver_down/helper.rb', line 66

def self.constantize(str)
  ::ActiveSupport::Inflector.constantize(str)
end

.module?(obj) ⇒ Boolean

Parameters:

  • obj (Object)

Returns:

  • (Boolean)


54
55
56
# File 'lib/diver_down/helper.rb', line 54

def self.module?(obj)
  Module === obj
end

.module_subclass?(mod) ⇒ Boolean

FIXME: I don’t know the best way to determine which class inherits from Module.

Returns:

  • (Boolean)


72
73
74
75
# File 'lib/diver_down/helper.rb', line 72

def self.module_subclass?(mod)
  mod.ancestors.size == 1 &&
    mod.class < Module
end

.normalize_module_name(obj) ⇒ String?

Returns if obj is anonymous module, return nil.

Parameters:

  • obj (Object, String, Module, Class)

Returns:

  • (String, nil)

    if obj is anonymous module, return nil



12
13
14
15
16
17
18
19
20
21
22
# File 'lib/diver_down/helper.rb', line 12

def self.normalize_module_name(obj)
  if String === obj
    obj
  else
    mod = resolve_module(obj)

    # Do not call the original method as much as possible
    CLASS_NAME_QUERY.bind_call(mod) ||
      (mod.name if mod.respond_to?(:name))
  end
end

.resolve_module(obj) ⇒ Module, Class

Note:

The object passed as an argument may be a Proxied BasicObject.

For example, the DSL of FactoryBot’s factory will add a new method in response to the invoked method name, so passed as an argument methods are not called within this method.

Returns:

  • (Module, Class)


29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/diver_down/helper.rb', line 29

def self.resolve_module(obj)
  if module?(obj) # Do not call method of this
    if module_subclass?(obj)
      obj.class
    else
      resolve_singleton_class(obj)
    end
  else
    k = INSTANCE_CLASS_QUERY.bind_call(obj)
    resolve_singleton_class(k)
  end
end

.resolve_singleton_class(obj) ⇒ Module, Class

Parameters:

  • obj (Module, Class)

Returns:

  • (Module, Class)


44
45
46
47
48
49
50
# File 'lib/diver_down/helper.rb', line 44

def self.resolve_singleton_class(obj)
  if obj.singleton_class?
    obj.attached_object
  else
    obj
  end
end