Module: CsvRowModel::Concerns::InheritedClassVar

Extended by:
ActiveSupport::Concern
Includes:
InvalidOptions
Included in:
Import::Presenter, Model
Defined in:
lib/csv_row_model/concerns/inherited_class_var.rb

Class Method Summary collapse

Methods included from InvalidOptions

check_and_merge_options

Class Method Details

.class_cache(variable_name) ⇒ Object (protected)

Memozies a inherited_class_variable_name

Parameters:

  • variable_name (Symbol)

    variable_name to cache against



114
115
116
117
118
119
120
# File 'lib/csv_row_model/concerns/inherited_class_var.rb', line 114

def class_cache(variable_name)
  #
  # equal to: (has @)inherited_class_variable_name ||= yield
  #
  cache_variable_name = inherited_class_variable_name(variable_name)
  instance_variable_get(cache_variable_name) || instance_variable_set(cache_variable_name, yield)
end

.clear_class_cache(variable_name) ⇒ Object

Clears the cache for a variable

Parameters:

  • variable_name (Symbol)

    variable_name to cache against



15
16
17
# File 'lib/csv_row_model/concerns/inherited_class_var.rb', line 15

def clear_class_cache(variable_name)
  instance_variable_set inherited_class_variable_name(variable_name), nil
end

.deep_clear_class_cache(variable_name) ⇒ Object (protected)

Clears the cache for a variable and the same variable for all it's dependant descendants

Parameters:

  • variable_name (Symbol)

    variable_name to cache against



106
107
108
109
110
# File 'lib/csv_row_model/concerns/inherited_class_var.rb', line 106

def deep_clear_class_cache(variable_name)
  ([self] + descendants).each do |descendant|
    descendant.try(:clear_class_cache, variable_name)
  end
end

.hidden_variable_name(variable_name) ⇒ Symbol (protected)

Returns the hidden variable name for class_cache.

Parameters:

  • variable_name (Symbol)

    class variable name based on

Returns:

  • (Symbol)

    the hidden variable name for class_cache



49
50
51
# File 'lib/csv_row_model/concerns/inherited_class_var.rb', line 49

def hidden_variable_name(variable_name)
  "@_#{variable_name}".to_sym
end

.inherited_ancestors(included_module = CsvRowModel::Concerns::InheritedClassVar) ⇒ Array<Module> (protected)

Returns inherited_ancestors of included_module (including self).

Parameters:

  • included_module (Module) (defaults to: CsvRowModel::Concerns::InheritedClassVar)

    module to search for

Returns:

  • (Array<Module>)

    inherited_ancestors of included_module (including self)



55
56
57
58
# File 'lib/csv_row_model/concerns/inherited_class_var.rb', line 55

def inherited_ancestors(included_module=CsvRowModel::Concerns::InheritedClassVar)
  included_model_index = ancestors.index(included_module)
  included_model_index == 0 ? [included_module] : ancestors[0..(included_model_index - 1)]
end

.inherited_class_hash(variable_name, options = {}) ⇒ Object (protected)

Parameters:

  • variable_name (Symbol)

    class variable name



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/csv_row_model/concerns/inherited_class_var.rb', line 22

def inherited_class_hash(variable_name, options={})
  options = check_and_merge_options(options, dependencies: [])

  options[:dependencies].each do |dependency_name|
    define_singleton_method dependency_name do
      class_cache(hidden_variable_name(dependency_name)) do
        send("_#{dependency_name}")
      end
    end
  end

  hidden_variable_name = hidden_variable_name(variable_name)
  define_singleton_method variable_name do
    inherited_class_var(hidden_variable_name, {}, :merge)
  end
  define_singleton_method "merge_#{variable_name}" do |merge_value|
    value = instance_variable_get(hidden_variable_name) || instance_variable_set(hidden_variable_name, {})

    deep_clear_class_cache(hidden_variable_name)
    options[:dependencies].each {|dependency_name| deep_clear_class_cache(hidden_variable_name(dependency_name)) }

    value.merge!(merge_value)
  end
end

.inherited_class_var(variable_name, default_value, merge_method) ⇒ Object (protected)

Returns a class variable merged across ancestors until inherited_class_module.

Parameters:

  • variable_name (Symbol)

    class variable name (recommend :@_variable_name)

  • default_value (Object)

    default value of the class variable

  • merge_method (Symbol)

    method to merge values of the class variable

Returns:

  • (Object)

    a class variable merged across ancestors until inherited_class_module



85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/csv_row_model/concerns/inherited_class_var.rb', line 85

def inherited_class_var(variable_name, default_value, merge_method)
  class_cache(variable_name) do
    value = default_value

    inherited_ancestors.each do |ancestor|
      ancestor_value = ancestor.instance_variable_get(variable_name)
      value = ancestor_value.public_send(merge_method, value) if ancestor_value.present?
    end

    value
  end
end

.inherited_class_variable_name(variable_name) ⇒ String (protected)

Returns the cache variable name for the cache.

Parameters:

  • variable_name (Symbol)

    variable_name to cache against

Returns:

  • (String)

    the cache variable name for the cache



100
101
102
# File 'lib/csv_row_model/concerns/inherited_class_var.rb', line 100

def inherited_class_variable_name(variable_name)
  "#{variable_name}_inherited_class_cache"
end

.inherited_custom_class(accessor_method_name, base_parent_class) ⇒ Class (protected)

grandparent -> parent -> self

grandparent has inherited_custom_class, but parent, doesn't.

then: base_parent_class -> grandparent::inherited_custom_class -> self::inherited_custom_class

Parameters:

  • accessor_method_name (Symbol)

    method to access the inherited_custom_class

  • base_parent_class (Class)

    class that the custom class inherits from if there's no parent

Returns:

  • (Class)

    a custom class with the inheritance following self. for example:



69
70
71
72
73
74
75
76
77
78
79
# File 'lib/csv_row_model/concerns/inherited_class_var.rb', line 69

def inherited_custom_class(accessor_method_name, base_parent_class)
  parent_class = inherited_ancestors[1..-1].find do |klass|
    klass.respond_to?(accessor_method_name)
  end.try(accessor_method_name)
  parent_class ||= base_parent_class

  klass = Class.new(parent_class)
  # how else can i get the current scopes name...
  klass.send(:define_singleton_method, :name, &eval("-> { \"#{name}#{base_parent_class.name.demodulize}\" }"))
  klass
end