r_kit 0.4.3 → 0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/lib/r_kit/active_record_utility/active_record_extend.rb +5 -30
  3. data/lib/r_kit/active_record_utility/database_schema_error.rb +3 -1
  4. data/lib/r_kit/active_record_utility/utilities/pool.rb +41 -0
  5. data/lib/r_kit/active_record_utility/utilities/publisher.rb +38 -0
  6. data/lib/r_kit/active_record_utility/{base → utilities}/series.rb +40 -15
  7. data/lib/r_kit/active_record_utility/utilities/tag.rb +30 -0
  8. data/lib/r_kit/active_record_utility.rb +12 -13
  9. data/lib/r_kit/backtrace.rb +1 -1
  10. data/lib/r_kit/core/loader/dependency.rb +3 -3
  11. data/lib/r_kit/core/loader/load_path.rb +5 -3
  12. data/lib/r_kit/core/loader.rb +14 -11
  13. data/lib/r_kit/core.rb +3 -1
  14. data/lib/r_kit/decoration/action_view_base_extend.rb +5 -4
  15. data/lib/r_kit/decoration/base/collection.rb +20 -0
  16. data/lib/r_kit/decoration/base/object.rb +21 -0
  17. data/lib/r_kit/decoration/base.rb +15 -19
  18. data/lib/r_kit/decoration/class.rb +103 -14
  19. data/lib/r_kit/decoration/dsl.rb +121 -0
  20. data/lib/r_kit/decoration/enumerable_extend.rb +9 -0
  21. data/lib/r_kit/decoration.rb +13 -6
  22. data/lib/r_kit/dsl/base/local_params.rb +6 -3
  23. data/lib/r_kit/dsl/base/thrust.rb +4 -2
  24. data/lib/r_kit/dsl/base.rb +14 -7
  25. data/lib/r_kit/dsl.rb +62 -11
  26. data/lib/r_kit/grid.rb +9 -8
  27. data/lib/r_kit/pagination/base/page.rb +1 -1
  28. data/lib/r_kit/pagination/base.rb +5 -24
  29. data/lib/r_kit/pagination/dsl.rb +15 -0
  30. data/lib/r_kit/pagination.rb +8 -5
  31. data/lib/r_kit/struct/safe_struct.rb +3 -0
  32. data/lib/r_kit/struct.rb +4 -2
  33. data/lib/r_kit/utility/basic_object_extend.rb +5 -0
  34. data/lib/r_kit/utility/kernel_extend.rb +48 -8
  35. data/lib/r_kit/utility/module_extend.rb +22 -1
  36. data/lib/r_kit/utility/simple_delegator_extend.rb +11 -2
  37. data/lib/r_kit/utility.rb +11 -1
  38. data/lib/r_kit/version.rb +1 -1
  39. metadata +12 -9
  40. data/lib/r_kit/active_record_utility/base/pool.rb +0 -29
  41. data/lib/r_kit/active_record_utility/base/publisher.rb +0 -28
  42. data/lib/r_kit/active_record_utility/base/tag.rb +0 -17
  43. data/lib/r_kit/active_record_utility/base.rb +0 -70
  44. data/lib/r_kit/decoration/active_record_extend.rb +0 -71
  45. data/lib/r_kit/pagination/active_record_extend.rb +0 -23
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 26da20a8c0d5ca239f0b25a5bbd39a3f87a3a115
4
- data.tar.gz: 20d9c76c01b2a7fbde0642e280c5ccbdf18fc77a
3
+ metadata.gz: bf5323abaf73afe8d62b58cb816884632fbdbdcf
4
+ data.tar.gz: a67bb90a5cdfa7a0b8bd9264107c1e2f8c80ac7b
5
5
  SHA512:
6
- metadata.gz: 9eb566e05f243773a8b3e3b5959510b3ea8ca9ca901843d22d19ec00200d984c198c571bfffdfe0b4c9ead1144e88d46ad00b3dd655b55778275e7c6e446c8fc
7
- data.tar.gz: 24aa528db16c96d5b1cb6b8bc5989c498a4a3b60ab05775cfc231cbac63196f3fe72894ec47411d576f6c34e5293882eb096fc833f4edae86962b2f4c57b5fb2
6
+ metadata.gz: 27e1256e0174889ca92e9283c207f07ed816fe6f7d4a8cc57defb009c0c4e0339ee5d206682dc9fbb67be275bdff60bb226b712abba852321f0d3fef348a12f6
7
+ data.tar.gz: c1a6450e8c1ea08ff888dd50e18a8a58753266b98f1cd5e3e5bc23966455acba675af93a095c08e3b721205c0d7630a245f5a5984364b1da887ab678a1c5fac8
@@ -1,39 +1,14 @@
1
1
  module RKit::ActiveRecordUtility::ActiveRecordExtend
2
2
 
3
- RKit::ActiveRecordUtility::UTILITIES.each do |utility, method_name|
4
- define_method method_name, ->(*args) do
5
- RKit::ActiveRecordUtility::Base.const_get(utility.classify).new(self, method_name: __method__).interfere *args
6
- end
7
- end
8
-
9
-
10
- def interferences_options_set utility, **options
11
- instance_variable_set "@_active_record_utilities_self", utility
12
- instance_variable_set "@_active_record_utilities_#{ utility }_options", options
13
- end
14
-
15
- def interferences_options_get utility = @_active_record_utilities_self
16
- instance_variable_get "@_active_record_utilities_#{ utility }_options"
17
- end
18
-
19
-
20
- def interfered? utility
21
- RKit::ActiveRecordUtility::Base.const_get(utility.classify).interfered? self
22
- rescue NameError
23
- false
24
- end
25
-
26
-
27
3
  def collection_finder **options
28
- collection = all
29
- collection = collection.pool options[:pool] if interfered? :pool
30
- collection = collection.published.publication_desc if interfered? :publisher
31
- collection = collection.series options[:series] if interfered? :series
32
- collection
4
+ all
5
+ .then(if: :acts_as_poolables?){ |collection| collection.pool options[:pool] }
6
+ .then(if: :acts_as_publishables?){ |collection| collection.published.publication_desc }
7
+ .then(if: :acts_as_seriables?){ |collection| collection.series options[:series] }
33
8
  end
34
9
 
35
10
  def instance_finder **options
36
- if interfered? :tag
11
+ if acts_as_taggables?
37
12
  tagged options[:tag]
38
13
  else
39
14
  find_by id: options[:id]
@@ -1,7 +1,9 @@
1
1
  class DatabaseSchemaError < StandardError
2
+ # TODO: does that class already exists ???
3
+ # TODO: allow to send a custom message, that will replace 2° & 3° lines
2
4
  def initialize base, method_name:;
3
5
  super %Q{
4
- WARNING - You tried to use the '#{ method_name }' DSL on '#{ base }',
6
+ DatabaseSchemaError: You tried to use the '#{ method_name }' DSL on '#{ base }',
5
7
  Your database is not ready for it yet,
6
8
  You can refer to the 'RKit::ActiveRecordUtlity' documentation.
7
9
  }
@@ -0,0 +1,41 @@
1
+ class RKit::ActiveRecordUtility::Pool
2
+ act_as_a_dsl
3
+
4
+ name :pool_dsl
5
+ method :acts_as_poolables
6
+ domain ActiveRecord::Base
7
+
8
+ allowed? do
9
+ table_exists? &&
10
+ column_names.include?("pool") &&
11
+ columns_hash["pool"].type == :string
12
+ end
13
+
14
+ restricted do
15
+ raise DatabaseSchemaError.new(self, method_name: pool_dsl.method)
16
+ end
17
+
18
+ params ->(**options){}
19
+
20
+ methods :class do
21
+
22
+ validates_presence_of :pool
23
+
24
+ pool_dsl.params.options[:in].then do |inclusion_in|
25
+ validates_inclusion_of :pool, in: inclusion_in
26
+ end
27
+
28
+ scope :pool, ->(pool){ pool && where(pool: pool) }
29
+ scope :pools, ->{ group(:pool).pluck(:pool) }
30
+ end
31
+
32
+ methods :decorator do
33
+ def pool_url
34
+ view.url_for [__class__, pool: pool]
35
+ end
36
+
37
+ def link_to_pool
38
+ view.link_to pool, pool_url, class: :btn
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,38 @@
1
+ class RKit::ActiveRecordUtility::Publisher
2
+ act_as_a_dsl
3
+
4
+ name :publisher_dsl
5
+ method :acts_as_publishables
6
+ domain ActiveRecord::Base
7
+
8
+ allowed? do
9
+ table_exists? &&
10
+ column_names.include_all?(["published", "published_at"]) &&
11
+ columns_hash["published"].type == :boolean &&
12
+ columns_hash["published_at"].type == :datetime
13
+ end
14
+
15
+ restricted do
16
+ raise DatabaseSchemaError.new(self, method_name: publisher_dsl.method)
17
+ end
18
+
19
+
20
+ methods :class do
21
+ before_validation do
22
+ self.published_at = Time.now if !published_at && published
23
+ end
24
+
25
+ validates_presence_of :published_at, if: :published
26
+
27
+ scope :published, ->{ where(published: true) }
28
+ scope :publication_asc, ->{ order("published_at ASC") }
29
+ scope :publication_desc, ->{ order("published_at DESC") }
30
+ end
31
+
32
+ methods :decorator do
33
+ def published_at
34
+ super().strftime "%a %e %b %Y"
35
+ end
36
+ end
37
+
38
+ end
@@ -1,6 +1,33 @@
1
- class RKit::ActiveRecordUtility::Base::Series < RKit::ActiveRecordUtility::Base
1
+ class RKit::ActiveRecordUtility::Series
2
+
3
+ # TODO: series must change to smthing bigger (maybe a service for itself)
4
+ # I want the "serie" to have its own DB-Table
5
+ # with tag, title, brief & custom-paginable
6
+ # (the custom paginable, could use only the pagination decorator, or a new dsl that inherit from paginable)
7
+ # and I want to be able to display the series's title+brief if needed
8
+ # (for example, when the scope "first_of_series" is called)
9
+ # TODO: maybe rename to "thread" ?
10
+
11
+ act_as_a_dsl
12
+
13
+ name :series_dsl
14
+ method :acts_as_seriables
15
+ domain ActiveRecord::Base
16
+
17
+ allowed? do
18
+ table_exists? &&
19
+ column_names.include_all?(["following_id", "series"]) &&
20
+ columns_hash["following_id"].type == :integer &&
21
+ columns_hash["series"].type == :string
22
+ end
23
+
24
+ restricted do
25
+ raise DatabaseSchemaError.new(self, method_name: series_dsl.method)
26
+ end
27
+
28
+
2
29
 
3
- instance_interferences do
30
+ methods :class do
4
31
  has_one :followed, class_name: name, foreign_key: "following_id"
5
32
  belongs_to :following, class_name: name
6
33
 
@@ -32,13 +59,15 @@ class RKit::ActiveRecordUtility::Base::Series < RKit::ActiveRecordUtility::Base
32
59
 
33
60
  # TODO: scope pour l'ordre dans une serie (pour le decorator pagination_tag)
34
61
 
35
- @@_active_record_utilities_series = {}
62
+ # @@_active_record_utilities_series = {}
36
63
  end
37
64
 
38
- class_interferences do
65
+
66
+ methods :instance do
39
67
  def series
40
- @@_active_record_utilities_series[read_attribute(:series)] ||= series_struct if read_attribute(:series)
41
- # TODO: if series cg-hanges, or new element added, series must be re-calculated
68
+ series_struct if read_attribute(:series)
69
+ # @@_active_record_utilities_series[read_attribute(:series)] ||= series_struct if read_attribute(:series)
70
+ # TODO: if series changes, or new element added, series must be re-calculated
42
71
  # maybe pre-calc this in after save
43
72
  end
44
73
 
@@ -55,7 +84,8 @@ class RKit::ActiveRecordUtility::Base::Series < RKit::ActiveRecordUtility::Base
55
84
  end
56
85
  end
57
86
 
58
- decorator_interferences do
87
+
88
+ methods :decorator do
59
89
  after_initialize do
60
90
  # TODO: this can't stay this way, if "serie" is pre-calculated
61
91
  # & shared accros instances & kept in memory (class variable)
@@ -73,8 +103,8 @@ class RKit::ActiveRecordUtility::Base::Series < RKit::ActiveRecordUtility::Base
73
103
  view.link_to series.name, series_url, class: :btn
74
104
  end
75
105
 
76
- if decorated_klass.columns_hash["title"]
77
- # I don't get this "showcase thing", we can delete that and just look into the view for the params
106
+ if decorated_class.columns_hash["title"]
107
+ # TODO: I don't get this "showcase thing", we can delete that and just look into the view for the params
78
108
  # Or in the collection, to see if the scope is applied (second solution is better)
79
109
  def series_title
80
110
  "#{ __getobj__.title } <small><i class='no-warp'>(vol #{ position_in_series })</i></small>".html_safe
@@ -132,10 +162,5 @@ class RKit::ActiveRecordUtility::Base::Series < RKit::ActiveRecordUtility::Base
132
162
  end
133
163
 
134
164
 
135
- def can_interfere?
136
- base.table_exists? &&
137
- base.column_names.include_all?(["following_id", "series"]) &&
138
- base.columns_hash["following_id"].type == :integer &&
139
- base.columns_hash["series"].type == :string
140
- end
165
+
141
166
  end
@@ -0,0 +1,30 @@
1
+ class RKit::ActiveRecordUtility::Tag
2
+ act_as_a_dsl
3
+
4
+ name :tag_dsl
5
+ method :acts_as_taggables
6
+ domain ActiveRecord::Base
7
+
8
+ allowed? do
9
+ table_exists? &&
10
+ column_names.include?("tag") &&
11
+ columns_hash["tag"].type == :string
12
+ end
13
+
14
+ restricted do
15
+ raise DatabaseSchemaError.new(self, method_name: tag_dsl.method)
16
+ end
17
+
18
+
19
+ methods :class do
20
+ validates_presence_of :tag
21
+ validates_uniqueness_of :tag
22
+
23
+ def tagged(tag) find_by tag: tag end
24
+ end
25
+
26
+ methods :instance do
27
+ def to_param() tag end
28
+ end
29
+
30
+ end
@@ -1,24 +1,23 @@
1
1
  class RKit::ActiveRecordUtility
2
- dependency :utilities
3
2
 
4
- load_path __FILE__, 'base.rb'
5
- load_path __FILE__, 'database_schema_error.rb'
3
+ dependency :dsl,
4
+ :utility
6
5
 
7
- load_path __FILE__, 'active_record_extend.rb'
6
+ load_path __FILE__,
7
+ 'active_record_extend',
8
+ 'database_schema_error'
8
9
 
9
10
 
10
- UTILITIES = {
11
- pool: :acts_as_poolables,
12
- publisher: :acts_as_publishables,
13
- series: :acts_as_seriables,
14
- tag: :acts_as_taggables,
15
- }
16
-
11
+ UTILITIES = Dir[File.join(File.dirname(__FILE__), "active_record_utility/utilities", "*.rb")].map do |file|
12
+ File.basename file, ".rb"
13
+ end
17
14
 
18
15
  config :all, true
19
16
 
20
- UTILITIES.each do |utility, _|
17
+ UTILITIES.each do |utility|
18
+
19
+
21
20
  alias_config utility, :all
22
- load_path __FILE__, "base/#{ utility }.rb", if: utility
21
+ load_path __FILE__, "utilities/#{ utility }", if: utility
23
22
  end
24
23
  end
@@ -4,6 +4,6 @@ class RKit::Backtrace
4
4
  # we may want to put a warning if the gem 'binding_of_caller' is not included
5
5
  # or we could directly include the C enxtention, with permission of the owner of the gem
6
6
 
7
- load_path __FILE__, 'kernel_extend.rb'
7
+ load_path __FILE__, 'kernel_extend'
8
8
 
9
9
  end
@@ -13,9 +13,9 @@ class Dependency
13
13
  # TODO: The dependency warning msg should be in service object
14
14
  def dependency!
15
15
  warn %Q{
16
- WARNING - #{ service.name } was implicitly loaded,
17
- As a dependency for #{ base }.
18
- You may want to load it explicitly.
16
+ WARNING - #{ service.name } will be implicitly loaded,
17
+ As a dependency for #{ base }.
18
+ You may want to load it explicitly.
19
19
  }
20
20
  service.load
21
21
  end
@@ -2,12 +2,14 @@ class LoadPath
2
2
  attr_accessor :_base,
3
3
  :file, :path, :priority, :conditions
4
4
 
5
- def initialize base, file:, path:, priority: 1/0.0
5
+ def initialize base, file:, path:, **options
6
6
  @_base = base
7
7
 
8
8
  @file = file
9
9
  @path = path
10
- @priority = priority
10
+
11
+ @priority = options.fetch :priority, 1/0.0
12
+ @conditions = options.slice :if, :unless
11
13
  end
12
14
 
13
15
 
@@ -17,7 +19,7 @@ class LoadPath
17
19
 
18
20
  def fullpath
19
21
  file.chomp! File.extname(file)
20
- File.expand_path(path, file)
22
+ File.expand_path(path, file) << ".rb"
21
23
  end
22
24
 
23
25
 
@@ -1,14 +1,14 @@
1
1
  class RKit::Core::Loader
2
2
  attr_accessor :_base, :load_paths, :dependencies
3
3
 
4
- @@loaded = []
4
+ @loaded = []
5
5
 
6
6
  def self.loaded
7
- @@loaded.map{ |name| name.demodulize.underscore }
7
+ @loaded.map{ |name| name.demodulize.underscore }
8
8
  end
9
9
 
10
10
  def self.loaded? name
11
- @@loaded.include? name
11
+ @loaded.include? name
12
12
  end
13
13
 
14
14
 
@@ -19,8 +19,12 @@ class RKit::Core::Loader
19
19
  end
20
20
 
21
21
 
22
- def dependency dependency
23
- dependencies << Dependency.new(_base, service: dependency)
22
+ # TODO: when a dependency is added, we must define in the opposite service a "dependency forbidden"
23
+ # TODO: in order to avoid recursive dependency
24
+ def dependency *services
25
+ services.each do |service|
26
+ dependencies << Dependency.new(_base, service: service)
27
+ end
24
28
  end
25
29
 
26
30
  def dependencies!
@@ -28,11 +32,10 @@ class RKit::Core::Loader
28
32
  end
29
33
 
30
34
 
31
- def load_path file, path, **options
32
- load_path = LoadPath.new _base, file: file, path: path, **options.slice(:priority)
33
- load_path.conditions = options.slice :if, :unless
34
-
35
- load_paths << load_path
35
+ def load_path file, *paths, **options
36
+ paths.each do |path|
37
+ load_paths << LoadPath.new(_base, file: file, path: path, **options.slice(:priority, :if, :unless))
38
+ end
36
39
  end
37
40
 
38
41
  def load_paths!
@@ -41,7 +44,7 @@ class RKit::Core::Loader
41
44
 
42
45
 
43
46
  def loaded!
44
- @@loaded << _base.name
47
+ __class__.instance_variable_get("@loaded") << _base.name
45
48
  end
46
49
 
47
50
 
data/lib/r_kit/core.rb CHANGED
@@ -23,7 +23,7 @@ class RKit::Core
23
23
 
24
24
  def with_sprockets file
25
25
  @_engine.sprockets = true
26
- load_path file, 'sass_extend.rb'
26
+ load_path file, 'sass_extend'
27
27
  end
28
28
 
29
29
 
@@ -65,8 +65,10 @@ class RKit::Core
65
65
  end
66
66
 
67
67
 
68
+ # TODO: configurer need some sort of wrapper & things, this needs to be largely improved
68
69
  require 'r_kit/core/configurer.rb'
69
70
 
71
+ # TODO: make engine mountable AFTER rails initialization
70
72
  require 'r_kit/core/engineer.rb'
71
73
 
72
74
  require 'r_kit/core/loader.rb'
@@ -1,20 +1,21 @@
1
1
  module RKit::Decoration::ActionViewBaseExtend
2
2
 
3
3
  def assign new_assigns
4
- _decorate_assigns new_assigns if RKit::Decoration.config.auto_decoration
4
+ decorate_assigns new_assigns
5
5
 
6
6
  super
7
7
  end
8
8
 
9
9
 
10
- def _decorate_assigns assigns
10
+ protected def decorate_assigns assigns
11
11
  assigns.dup.each do |key, value|
12
- assigns[key] = _decorate value
12
+ assigns[key] = decorate value
13
13
  end
14
14
  end
15
15
 
16
- def _decorate assign
16
+ protected def decorate assign
17
17
  if assign.respond_to? :decorate
18
+ p "go in decorate"
18
19
  assign.decorate view_context: self
19
20
  else
20
21
  assign
@@ -0,0 +1,20 @@
1
+ class RKit::Decoration::Collection < CollectionDelegator
2
+ include RKit::Decoration::Base
3
+
4
+
5
+ attr_accessor :safe_mode
6
+
7
+ def safe() tap{ @safe_mode = true } end
8
+ def unsafe() tap{ @safe_mode = false } end
9
+
10
+
11
+ def each &block
12
+ collection.each do |object|
13
+ if safe_mode && object.dont_respond_to?(:decorate)
14
+ block.call object
15
+ else
16
+ block.call object.decorate(view_context: view)
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,21 @@
1
+ class RKit::Decoration::Object < SimpleDelegator
2
+ include RKit::Decoration::Base
3
+
4
+
5
+ singleton_attr_reader :decorated_class
6
+ singleton_attr_reader :after_initialize_procs, default: proc{ [] }
7
+
8
+ def self.after_initialize &block
9
+ after_initialize_procs << block
10
+ end
11
+
12
+ def after_initialize!
13
+ decorator_class.after_initialize_procs.each{ |after_initialize_proc| self.instance_eval &after_initialize_proc }
14
+ end
15
+
16
+
17
+ def initialize obj, view_context: nil
18
+ super
19
+ after_initialize!
20
+ end
21
+ end
@@ -1,35 +1,31 @@
1
- require 'delegate'
1
+ module RKit::Decoration::Base
2
2
 
3
- class RKit::Decoration::Base < SimpleDelegator
3
+ def initialize object, view_context: nil
4
+ @view_context = view_context
5
+ super object
6
+ end
7
+
8
+ alias :decorator_class :class
9
+ delegate :class, to: :__getobj__
4
10
 
5
- singleton_attr_reader :decorated_klass
6
- singleton_attr_reader :after_initialize_procs, default: proc{ [] }
7
11
 
8
- def self.after_initialize &block
9
- after_initialize_procs << block
12
+ def decorate *args
13
+ self
10
14
  end
11
15
 
12
- def initialize obj, view_context: nil
13
- @_view_context = view_context
14
- super obj
16
+ def decorated?() true end
15
17
 
16
- decorator_klass.after_initialize_procs.each{ |after_initialize_proc| self.instance_eval &after_initialize_proc }
18
+ def raw
19
+ __getobj__
17
20
  end
18
21
 
19
- alias :decorator_klass :class
20
- delegate :class, to: :__getobj__
21
22
 
22
-
23
- def _view_context
23
+ private def view_context
24
24
  backtrace{ |obj| obj.is_a? ActionView::Base } || backtrace{ |obj| obj.respond_to? :view_context }.view_context
25
25
  end
26
26
 
27
27
  def view
28
- @_view_context ||= _view_context
28
+ @view_context ||= view_context
29
29
  end
30
30
 
31
-
32
- def === object
33
- self == object || __getobj__ == object
34
- end
35
31
  end
@@ -1,22 +1,111 @@
1
1
  class RKit::Decoration::Class
2
2
 
3
- module OpenClass
4
- refine Class do
5
- def new super_class = Object, **options, &block
6
- super(super_class, &block).tap do |klass|
7
- options.each{ |key, value| klass.instance_variable_set "@#{ key }", value }
8
- end
9
- end
3
+ class << self
4
+ alias :basic_new :new
5
+ def new *args, &block
6
+ basic_new(*args, &block).decorator
10
7
  end
11
8
  end
12
- using OpenClass
13
9
 
14
- # TODO: improve this "new" method, in order to move the creation of the decoraor klass for ARextend to here
15
- # ot should be able to accept a proc, a module, a class, or nil(autodetect)
16
- # -- While doing so, U could move the logic of Class.to_module && Module.to_class && Proc.to_class in "utilities" (or new rkit service)
17
- def self.new decorated_klass, &block
18
- Class.new(RKit::Decoration::Base, decorated_klass: decorated_klass, &block).tap do |klass|
19
- klass.class_eval{ alias :"#{ decorated_klass.demodulize.underscore }" :__getobj__ }
10
+
11
+ def initialize decorated, from: nil, &block
12
+ @decorated = decorated
13
+ @from = from
14
+ @block = block || proc{}
15
+ end
16
+
17
+
18
+ def decorator
19
+ decorator_from(@from)
20
+ .tap{ |decorator| decorator.instance_variable_set "@decorated_class", @decorated }
21
+ .tap{ |decorator| decorator.class_eval{ alias :"#{ decorated_class.demodulize.underscore }" :__getobj__ } }
22
+ .tap{ |decorator| decorator.class_eval &@block }
23
+ end
24
+
25
+
26
+
27
+ protected def decorator_from from
28
+ send "decorator_from_#{ from.class.underscore }", from
29
+ end
30
+
31
+
32
+ protected def decorator_from_nil_class *_
33
+ decorator_from "#{ @decorated.demodulize }Decorator"
34
+ end
35
+
36
+ protected def decorator_from_string name
37
+ decorator_from(
38
+ @decorated
39
+ .namespace
40
+ .const_get name, default: Class.new(RKit::Decoration::Object)
41
+ )
42
+ end
43
+
44
+ alias :decorator_from_symbol :decorator_from_string
45
+
46
+ # TODO: method module_to_class(superclass)
47
+ def decorator_from_module mod
48
+ mod
49
+ .namespace
50
+ .const_replace mod.demodulize,
51
+ Class.new(RKit::Decoration::Object){ include mod }
52
+ end
53
+
54
+ def decorator_from_class base
55
+ if base <=> RKit::Decoration::Object
56
+ base
57
+ else
58
+ # TODO: method class_to_module
59
+ # TODO: method class.add_ancestor(superclass)
60
+ base.tap do |base|
61
+ base.send :include, Module.new{ include refine(RKit::Decoration::Object){} }
62
+ base.extend Module.new{ include refine(RKit::Decoration::Object.singleton_class){} }
63
+ base.instance_variable_set "@decorated_class", @decorated
64
+ base.class_eval{ alias :"#{ decorated_class.demodulize.underscore }" :__getobj__ }
65
+ end
20
66
  end
21
67
  end
22
68
  end
69
+
70
+
71
+ # # TODO: all the methods below this comment should be private, even more, they should be in a "decorator_finder_creator_definer", and not included in active_record. SRP guys !
72
+ # def define_decorator arg
73
+ # @decorator_klass = decorator_klass_from arg
74
+ # @decorator_klass
75
+ # end
76
+ #
77
+ #
78
+ # def decorator_klass_from arg
79
+ # send "decorator_klass_from_#{ arg.class.name.underscore }", arg
80
+ # end
81
+ #
82
+ # def decorator_klass_from_nil_class *args
83
+ # decorator_klass_from "#{ name }Decorator".constantize
84
+ # end
85
+ #
86
+ # def decorator_klass_from_class base
87
+ # if base <=> RKit::Decoration::Base
88
+ # base
89
+ # else
90
+ # base.tap do |base|
91
+ # base.send :include, Module.new{ include refine(RKit::Decoration::Base){} }
92
+ # base.extend Module.new{ include refine(RKit::Decoration::Base.singleton_class){} }
93
+ # base.instance_variable_set "@decorated_klass", self
94
+ # base.class_eval{ alias :"#{ decorated_klass.demodulize.underscore }" :__getobj__ }
95
+ # end
96
+ # end
97
+ # end
98
+ #
99
+ # def decorator_klass_from_module mod
100
+ # namespace = (mod.name.deconstantize.presence || 'Object').constantize
101
+ # const_name = mod.name.demodulize
102
+ #
103
+ # namespace.send :remove_const, const_name
104
+ # namespace.const_set const_name, RKit::Decoration::Class.new(self){ include mod }
105
+ # end
106
+ #
107
+ # def decorator_klass_from_proc block
108
+ # (name.deconstantize.presence || 'Object')
109
+ # .constantize
110
+ # .const_set "#{ name.demodulize }Decorator", RKit::Decoration::Class.new(self, &block)
111
+ # end