capsula 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: de1e116a89071a460417f16918fbc8ea0871ba2217a3b513d90f76028ff789c0
4
+ data.tar.gz: d66bf5ca919d2df33b664b5e50d9dab8afd3866a115ce47ab5e458335610d6fc
5
+ SHA512:
6
+ metadata.gz: 9919c5c93000fa52a3615c41bb579ca202be4805b7d879219b59cb0b941ed214b07bf5d260ae5c3775bd0494d3c4abe808b92fb510942cc277243a575bde7dd8
7
+ data.tar.gz: d467d3cadada0ffb8cf7cb7ccc86b32b683a30e97b4a3aab079df1d101583a57c934673553a824544359011c0cdefa1fff2d2969997288a16dbaaf7fe54194d2
@@ -0,0 +1,50 @@
1
+ *.gem
2
+ *.rbc
3
+ /.config
4
+ /coverage/
5
+ /InstalledFiles
6
+ /pkg/
7
+ /spec/reports/
8
+ /spec/examples.txt
9
+ /test/tmp/
10
+ /test/version_tmp/
11
+ /tmp/
12
+
13
+ # Used by dotenv library to load environment variables.
14
+ # .env
15
+
16
+ ## Specific to RubyMotion:
17
+ .dat*
18
+ .repl_history
19
+ build/
20
+ *.bridgesupport
21
+ build-iPhoneOS/
22
+ build-iPhoneSimulator/
23
+
24
+ ## Specific to RubyMotion (use of CocoaPods):
25
+ #
26
+ # We recommend against adding the Pods directory to your .gitignore. However
27
+ # you should judge for yourself, the pros and cons are mentioned at:
28
+ # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
29
+ #
30
+ # vendor/Pods/
31
+
32
+ ## Documentation cache and generated files:
33
+ /.yardoc/
34
+ /_yardoc/
35
+ /doc/
36
+ /rdoc/
37
+
38
+ ## Environment normalization:
39
+ /.bundle/
40
+ /vendor/bundle
41
+ /lib/bundler/man/
42
+
43
+ # for a library or gem, you might want to ignore these files since the code is
44
+ # intended to run in multiple environments; otherwise, check them in:
45
+ # Gemfile.lock
46
+ # .ruby-version
47
+ # .ruby-gemset
48
+
49
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
50
+ .rvmrc
data/Gemfile ADDED
@@ -0,0 +1,14 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
3
+
4
+ group :development do
5
+ gem 'guard'
6
+ gem 'guard-rspec'
7
+ gem 'guard-bundler'
8
+ gem 'rb-readline'
9
+ end
10
+
11
+ group :test do
12
+ gem 'rspec'
13
+ gem 'simplecov', require: false
14
+ end
@@ -0,0 +1,85 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ capsula (0.0.1)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ coderay (1.1.2)
10
+ diff-lcs (1.3)
11
+ docile (1.3.1)
12
+ ffi (1.10.0)
13
+ formatador (0.2.5)
14
+ guard (2.15.0)
15
+ formatador (>= 0.2.4)
16
+ listen (>= 2.7, < 4.0)
17
+ lumberjack (>= 1.0.12, < 2.0)
18
+ nenv (~> 0.1)
19
+ notiffany (~> 0.0)
20
+ pry (>= 0.9.12)
21
+ shellany (~> 0.0)
22
+ thor (>= 0.18.1)
23
+ guard-bundler (2.2.1)
24
+ bundler (>= 1.3.0, < 3)
25
+ guard (~> 2.2)
26
+ guard-compat (~> 1.1)
27
+ guard-compat (1.2.1)
28
+ guard-rspec (4.7.3)
29
+ guard (~> 2.1)
30
+ guard-compat (~> 1.1)
31
+ rspec (>= 2.99.0, < 4.0)
32
+ json (2.1.0)
33
+ listen (3.1.5)
34
+ rb-fsevent (~> 0.9, >= 0.9.4)
35
+ rb-inotify (~> 0.9, >= 0.9.7)
36
+ ruby_dep (~> 1.2)
37
+ lumberjack (1.0.13)
38
+ method_source (0.9.2)
39
+ nenv (0.3.0)
40
+ notiffany (0.1.1)
41
+ nenv (~> 0.1)
42
+ shellany (~> 0.0)
43
+ pry (0.12.2)
44
+ coderay (~> 1.1.0)
45
+ method_source (~> 0.9.0)
46
+ rb-fsevent (0.10.3)
47
+ rb-inotify (0.10.0)
48
+ ffi (~> 1.0)
49
+ rb-readline (0.5.5)
50
+ rspec (3.8.0)
51
+ rspec-core (~> 3.8.0)
52
+ rspec-expectations (~> 3.8.0)
53
+ rspec-mocks (~> 3.8.0)
54
+ rspec-core (3.8.0)
55
+ rspec-support (~> 3.8.0)
56
+ rspec-expectations (3.8.2)
57
+ diff-lcs (>= 1.2.0, < 2.0)
58
+ rspec-support (~> 3.8.0)
59
+ rspec-mocks (3.8.0)
60
+ diff-lcs (>= 1.2.0, < 2.0)
61
+ rspec-support (~> 3.8.0)
62
+ rspec-support (3.8.0)
63
+ ruby_dep (1.5.0)
64
+ shellany (0.0.1)
65
+ simplecov (0.16.1)
66
+ docile (~> 1.1)
67
+ json (>= 1.8, < 3)
68
+ simplecov-html (~> 0.10.0)
69
+ simplecov-html (0.10.2)
70
+ thor (0.20.3)
71
+
72
+ PLATFORMS
73
+ ruby
74
+
75
+ DEPENDENCIES
76
+ capsula!
77
+ guard
78
+ guard-bundler
79
+ guard-rspec
80
+ rb-readline
81
+ rspec
82
+ simplecov
83
+
84
+ BUNDLED WITH
85
+ 1.16.6
@@ -0,0 +1,10 @@
1
+ guard :rspec, cmd: 'rspec' do
2
+ watch(%r{^spec/.+_spec\.rb$})
3
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
4
+ watch('spec/spec_helper.rb') { "spec" }
5
+ end
6
+
7
+ guard 'bundler' do
8
+ watch('Gemfile')
9
+ watch(/^.+\.gemspec/)
10
+ end
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2019 Rodion
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,94 @@
1
+ # Capsula
2
+ The tool for encapsulating (preloading, including) related objects into **any** object.
3
+
4
+ ## How to use:
5
+
6
+ ```ruby
7
+ starships = <get_your_space_fleet>
8
+
9
+ StarshipsEncapsulator.new(starships).plans(
10
+ :fuel, :oxygen, :food, { spaceman: [:space_suit] }
11
+ ).encapsulate
12
+
13
+ # Now let's get a suit for our spaceman:
14
+ starships.first&.spaceman&.space_suit
15
+ => <awesome space suit> # Capsula's wrapper answers
16
+ ```
17
+
18
+ Let's see how `StarshipsEncapsulator` looks:
19
+
20
+ ```ruby
21
+ class StarshipsEncapsulator < Capsula::Base
22
+ plan_for :fuel,
23
+ src_key: :fuel_id,
24
+ dst_key: :id,
25
+ dst_loader: ->(ids,opt){ MyFuelStation.find_fuel_by_ids(ids) }
26
+ # Example loader for ActiveRecord model Fuel:
27
+ # dst_loader: ->(ids,opt){ Fuel.where(id: ids).includes(opt[:plans]).to_a }
28
+
29
+ # Plans for other relations...
30
+ end
31
+ ```
32
+ Definition for `src_key` and `dst_key` can be skipped if they values are `:fuel_id` (`<key_name>_id`) and `:id`
33
+
34
+
35
+ Also, for key-definition can be used lambdas:
36
+
37
+ ```ruby
38
+ src_key: ->(o){ o.some_hash_data.fetch(:fuel_id, default: 'A-95') }
39
+ dst_key: ->(o){ o.extact_fuel_id_from_octane_number }
40
+ ```
41
+
42
+ ## How it works:
43
+
44
+ All objects is wrapping into special transparent wrapper which
45
+ translate all methods to wrapped object, except methods-names which was used for encapsulating before:
46
+
47
+ ```ruby
48
+ StarshipsEncapsulator.new(starships).plan(:fuel, :oxygen).encapsulate
49
+ starships.first.oxygen
50
+ => <oxygen> # instant response, because already present in Capsula
51
+ ```
52
+
53
+ Rest methods transparently sending to wrapped object:
54
+
55
+ ```ruby
56
+ starships.first.food
57
+ => <pizza> # returns to Mothership and cook pizza
58
+ ```
59
+
60
+ ## Custom encapsulators (dst_loaders):
61
+ For difficult preloading logic can be used custom loader:
62
+
63
+ ```ruby
64
+ class CustomLoader
65
+ def initialize items:, opt: {}
66
+ @items = items; @opt = opt; @store = [];
67
+ end
68
+
69
+ # This method is triggered by Capsula
70
+ def collect_ids_and_load_relations
71
+ ids = @items.map{ |i| i.fuel_id }
72
+ @store = Fuel.where(id: ids).to_a
73
+ end
74
+
75
+ # This method is calling by Capsula during encapsulation
76
+ def get_preloads_for_object starship
77
+ @store.find { |fuel| starship.fuel_id == fuel.id }
78
+ end
79
+ end
80
+
81
+
82
+ class StarshipsEncapsulator < Capsula::Base
83
+ plan_for :fuel, delegate_to: CustomLoader
84
+ end
85
+ ```
86
+
87
+ ## Contributing
88
+
89
+ * Fork the project.
90
+ * Run `bundle install`
91
+ * Run `bundle exec guard`
92
+ * Make your feature addition or bug fix.
93
+ * Add tests for it. This is important.
94
+ * Send me a pull request.
@@ -0,0 +1,18 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'capsula'
3
+ s.version = '0.0.2'
4
+ s.date = '2019-02-04'
5
+ s.summary = 'Encapsulating tool'
6
+ s.description = 'The tool for encapsulating (preloading, including) related objects'
7
+ s.authors = ['Rodion V']
8
+ s.email = 'rodion.v@devaer.com'
9
+ s.homepage = 'https://github.com/brlo/capsula'
10
+ s.license = 'MIT'
11
+
12
+ all_files = `git ls-files`.split("\n")
13
+ test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
14
+
15
+ s.files = all_files - test_files
16
+ s.test_files = test_files
17
+ s.require_paths = ['lib']
18
+ end
@@ -0,0 +1,3 @@
1
+ require 'capsula/wrapper'
2
+ require 'capsula/encapsulator'
3
+ require 'capsula/base'
@@ -0,0 +1,62 @@
1
+ module Capsula
2
+ class Base
3
+
4
+ ##
5
+ # Base class for inheritence when creating new Encapsulators
6
+ #
7
+
8
+ def initialize items
9
+ @items = items
10
+ end
11
+
12
+ def plans *keys
13
+ @keys = keys.flatten.compact.uniq
14
+ self
15
+ end
16
+
17
+ def encapsulate
18
+ Encapsulator.new(
19
+ items: @items,
20
+ declarations: self.class.merged_plans_declarations,
21
+ keys: @keys
22
+ ).preload_and_encapsulate
23
+ end
24
+
25
+ class << self
26
+
27
+ # DSL method
28
+ def plan_for relation_key, **opt
29
+ add_to_plans_declaration relation_key: relation_key, **opt
30
+ end
31
+
32
+ # declarations from current class and from all parents, if such present
33
+ def merged_plans_declarations
34
+ return @merged_plans_declarations if defined?(@merged_plans_declarations)
35
+ @merged_plans_declarations = plans_declarations || {}
36
+
37
+ sc = self
38
+ while (sc = sc.superclass).respond_to?(:plans_declarations)
39
+ @merged_plans_declarations.merge!(sc.plans_declarations)
40
+ end
41
+ @merged_plans_declarations
42
+ end
43
+
44
+ private
45
+
46
+ # declaration only for current class
47
+ def plans_declarations
48
+ @plans_declarations
49
+ end
50
+
51
+ def add_to_plans_declaration relation_key:, **opt
52
+ @plans_declarations ||= {}
53
+ opt[:dst_key] = :id unless opt.has_key?(:dst_key)
54
+ opt[:src_key] = :"#{relation_key}_id" unless opt.has_key?(:src_key)
55
+
56
+ @plans_declarations[relation_key] = opt
57
+ end
58
+
59
+ end
60
+
61
+ end
62
+ end
@@ -0,0 +1,166 @@
1
+ module Capsula
2
+ class Encapsulator
3
+
4
+ ##
5
+ # Main encapsulator functionality
6
+ #
7
+
8
+ def initialize items:, declarations:, keys:
9
+ # wrap up not wrapped obects
10
+ @items = wrap_non_wrapped(items)
11
+ @declarations = declarations
12
+
13
+ @keys = []
14
+ @keys_values = {}
15
+
16
+ ##
17
+ # Parse all declarations by first-level plans.
18
+ #
19
+ # We get a nested plans structure:
20
+ # [
21
+ # {fruits: [:tree, {bugs: [:locations]]},
22
+ # :vegetables
23
+ # ]
24
+ # For current objects which we will encapsulate now
25
+ # (call it first-level objects)
26
+ # we need to preload only :fruits and :vegetables,
27
+ # But when the turn comes to encapsulate :fruits,
28
+ # we will transfer plans for :fruits to fruits-encapsulator,
29
+ # and let him deside how to encapsulate tree and bugs into fruits,
30
+ # and then, bugs-encapsulator shoud encapsulate locations and so on.
31
+ #
32
+ keys.each do |i|
33
+ if i.is_a?(Hash)
34
+ k, v = i.first
35
+ @keys << k
36
+ @keys_values[k] = v
37
+ else
38
+ @keys << i
39
+ end
40
+ end
41
+
42
+ # for preloaded objects
43
+ @collections = {}
44
+ end
45
+
46
+ def preload_and_encapsulate
47
+ if (@keys - @declarations.keys).any?
48
+ raise StandardError.new("unknown relation keys: #{ (@keys - @declarations.keys) }")
49
+ end
50
+
51
+ preload
52
+
53
+ encapsulate
54
+
55
+ @items
56
+ end
57
+
58
+ def preload
59
+ @keys.each do |key|
60
+ dec = @declarations[key]
61
+ opt = build_encapsulator_options(key)
62
+
63
+ if dec.has_key?(:delegate_to)
64
+ # Delegate to user's encapsulator
65
+ preload_by_delegator(dec[:delegate_to], key, opt)
66
+ else
67
+ # Use native encapsulator
68
+ native_preload(key, dec, opt)
69
+ end
70
+ end
71
+ end
72
+
73
+ def encapsulate
74
+ @collections.each do |plan_key, accessories|
75
+ if accessories.has_key?(:delegator)
76
+ # Delegate to user's encapsulator
77
+ encapsulate_by_delegator(
78
+ accessories[:delegator],
79
+ plan_key
80
+ )
81
+ else
82
+ # Use native encapsulator
83
+ native_encapsulation(
84
+ plan_key,
85
+ accessories[:collection],
86
+ accessories[:declaration]
87
+ )
88
+ end
89
+ end
90
+ end
91
+
92
+ private
93
+
94
+ def preload_by_delegator delegator, key, opt
95
+ d = delegator.new(items: @items, opt: opt)
96
+ d.collect_ids_and_load_relations
97
+ @collections[key] = { delegator: d }
98
+ end
99
+
100
+ def native_preload key, dec, opt
101
+ # collect relation ids
102
+ ids = @items.map do |o|
103
+ get_key(o, dec[:src_key])
104
+ end.flatten.uniq.compact
105
+
106
+ # preload relations
107
+ @collections[key] = {
108
+ collection: (ids.any? ? dec[:dst_loader].call(ids,opt) : []),
109
+ declaration: dec
110
+ }
111
+ end
112
+
113
+ def encapsulate_by_delegator delegator, plan_key
114
+ @items.each do |i|
115
+ val = delegator.get_preloads_for_object(i)
116
+ i[plan_key] = val
117
+ end
118
+ end
119
+
120
+ def native_encapsulation plan_key, preloaded_collection, declaration
121
+ col = preloaded_collection
122
+ dec = declaration
123
+
124
+ @items.each do |i|
125
+ src_id = get_key(i, dec[:src_key])
126
+
127
+ val = if src_id.is_a?(Array)
128
+ # if object has many links to related objects (Array)
129
+ col.select{|c| src_id.include?(c.id) }
130
+ else
131
+ # only one link
132
+ col.find{|c| get_key(c, dec[:dst_key]) == src_id }
133
+ end
134
+ i[plan_key] = val
135
+ end
136
+ end
137
+
138
+ def get_key _object_, key_or_lambda
139
+ case key_or_lambda
140
+ when Symbol, String
141
+ _object_.send(key_or_lambda)
142
+ when Proc
143
+ key_or_lambda.call(_object_)
144
+ else
145
+ nil
146
+ end
147
+ end
148
+
149
+ def build_encapsulator_options key
150
+ {
151
+ plans: @keys_values[key] || []
152
+ }
153
+ end
154
+
155
+ def wrap_non_wrapped items
156
+ items.map do |item|
157
+ if item.class == Wrapper
158
+ item
159
+ else
160
+ Wrapper.new(item)
161
+ end
162
+ end
163
+ end
164
+
165
+ end
166
+ end
@@ -0,0 +1,57 @@
1
+ module Capsula
2
+ class Wrapper
3
+
4
+ ##
5
+ # Objects-wrapper which is giving to objects ability to encapsulate other objects
6
+ #
7
+
8
+ attr_reader :store
9
+ attr_accessor :item
10
+
11
+ def initialize _object_
12
+ @item = _object_
13
+ @store = {}
14
+ end
15
+
16
+ # w=Capsula::Wrapper.new(1)
17
+ # => 1
18
+ # w[:a] = 2
19
+ # => 2
20
+ # w
21
+ # => 1
22
+ # w.a
23
+ # => 2
24
+ def []= key, val
25
+ @store[key] = val
26
+ end
27
+
28
+ def inspect
29
+ @item.inspect
30
+ end
31
+
32
+ def respond_to? name, is_lookup_private = false
33
+ self.store.include?(name) || @item.respond_to?(name, is_lookup_private)
34
+ end
35
+
36
+ # TODO:
37
+ # at first - call for wrapper, then for item (if working with hash)
38
+ # []
39
+ # fetch
40
+ # is_a?
41
+
42
+ if Object.respond_to?(:try)
43
+ def try *a, &b
44
+ @item.try(*a, &b)
45
+ end
46
+ end
47
+
48
+ def method_missing(method, *args, &block)
49
+ if store.has_key?(method)
50
+ store[method]
51
+ else
52
+ @item.send(method, *args, &block)
53
+ end
54
+ end
55
+
56
+ end
57
+ end
@@ -0,0 +1,90 @@
1
+ require 'capsula'
2
+
3
+ RSpec.describe Capsula do
4
+ let(:klass){ Class.new(Capsula::Base) }
5
+ let(:a) { Struct.new(:b_id) }
6
+ let(:b) { Struct.new(:id) }
7
+
8
+ describe 'User can' do
9
+ it 'declare new encapsulation plan' do
10
+ klass.plan_for(:b, src_key: :b_id, dst_key: :id, dst_loader: ->(i,o){})
11
+ plans = klass.instance_variable_get('@plans_declarations')
12
+ expect(plans).to have_key(:b)
13
+ end
14
+
15
+ it 'preloads objects collection' do
16
+ klass.plan_for(
17
+ :b,
18
+ src_key: :b_id,
19
+ dst_key: :id,
20
+ dst_loader: ->(ids,opt){ ids.map{ |i| b.new(i) } }
21
+ )
22
+ objects = [1,2].map{ |i| a.new(i) }
23
+ objects = klass.new(objects).plans(:b).encapsulate
24
+
25
+ puts objects.first.b
26
+
27
+ expect(objects.first).to respond_to(:b)
28
+ expect(objects.first).to be_a(Capsula::Wrapper)
29
+ expect(objects.first.b.id).to be == objects.first.b_id
30
+ end
31
+
32
+ it 'use lambdas in place of symbols for key-declaration' do
33
+ klass.plan_for(
34
+ :b,
35
+ src_key: ->(o){ o.b_id },
36
+ dst_key: ->(o){ o.id },
37
+ dst_loader: ->(ids,opt){ ids.map{ |i| b.new(i) } }
38
+ )
39
+
40
+ objects = [1,2].map{ |i| a.new(i) }
41
+ objects = klass.new(objects).plans(:b).encapsulate
42
+
43
+ expect(objects.first).to respond_to(:b)
44
+ expect(objects.first).to be_a(Capsula::Wrapper)
45
+ expect(objects.first.b.id).to be == objects.first.b_id
46
+ end
47
+
48
+ it 'use default keys-declaration' do
49
+ klass.plan_for(
50
+ :b,
51
+ dst_loader: ->(ids,opt){ ids.map{ |i| b.new(i) } }
52
+ )
53
+
54
+ objects = [1,2].map{ |i| a.new(i) }
55
+ objects = klass.new(objects).plans(:b).encapsulate
56
+
57
+ expect(objects.first).to respond_to(:b)
58
+ expect(objects.first).to be_a(Capsula::Wrapper)
59
+ expect(objects.first.b.id).to be == objects.first.b_id
60
+ end
61
+
62
+ it 'use custom loader' do
63
+ custom_loader = Class.new do
64
+ def initialize items:, opt: {}
65
+ @items = items; @opt = opt; @store = []; @b = Struct.new(:id)
66
+ end
67
+
68
+ def collect_ids_and_load_relations
69
+ ids = @items.map{ |i| i.b_id }
70
+ @store = ids.map{ |id| @b.new(id) }
71
+ end
72
+
73
+ def get_preloads_for_object o
74
+ @store.find { |a| o.b_id == a.id }
75
+ end
76
+ end
77
+
78
+ klass.plan_for(:b, delegate_to: custom_loader)
79
+
80
+ objects = [1,2].map{ |i| a.new(i) }
81
+ objects = klass.new(objects).plans(:b).encapsulate
82
+
83
+ expect(objects.first).to respond_to(:b)
84
+ expect(objects.first).to be_a(Capsula::Wrapper)
85
+ expect(objects.first.b.id).to be == objects.first.b_id
86
+ end
87
+
88
+ end
89
+
90
+ end
metadata ADDED
@@ -0,0 +1,55 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: capsula
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Rodion V
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-02-04 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: The tool for encapsulating (preloading, including) related objects
14
+ email: rodion.v@devaer.com
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - ".gitignore"
20
+ - Gemfile
21
+ - Gemfile.lock
22
+ - Guardfile
23
+ - LICENSE
24
+ - README.md
25
+ - capsula.gemspec
26
+ - lib/capsula.rb
27
+ - lib/capsula/base.rb
28
+ - lib/capsula/encapsulator.rb
29
+ - lib/capsula/wrapper.rb
30
+ - spec/capsula_spec.rb
31
+ homepage: https://github.com/brlo/capsula
32
+ licenses:
33
+ - MIT
34
+ metadata: {}
35
+ post_install_message:
36
+ rdoc_options: []
37
+ require_paths:
38
+ - lib
39
+ required_ruby_version: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ required_rubygems_version: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ requirements: []
50
+ rubygems_version: 3.0.2
51
+ signing_key:
52
+ specification_version: 4
53
+ summary: Encapsulating tool
54
+ test_files:
55
+ - spec/capsula_spec.rb