pinball 0.0.2 → 0.0.3

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c2cda464327444a1c7fd499861105269f0272f3f
4
- data.tar.gz: b99ffa3a55fbd7a9b183e699fd44fdec4181f345
3
+ metadata.gz: a0a151b6a0ce9ddb00755568ae644cb809e6f13a
4
+ data.tar.gz: b842f2c2e9acacd61444d82fa411a03bd6769e47
5
5
  SHA512:
6
- metadata.gz: df4f00d3febebbf691c82205ac77625c918c4afe07f0c57c839d3f7f9942e24d4d5fd098a5962f18367068c64a1c7337257212f78d28c62c1498919c64270659
7
- data.tar.gz: 1a88d82d7c6e6ce0d10777a316eb82dc5fe8dd39c3eb47b21e202b86752693081e8f5e573cd3e20eb154f5b70b52fbc7889139e0bd7bec2c7d72f9845e44c75e
6
+ metadata.gz: 828227b6d3b7847301a7958d325e377ca2833c7f1e7eb55af04dfe16b1eed7d3c4615511fa74ca2bebfbb9e9b8792298828da307c481f30e45cbd402f98a095f
7
+ data.tar.gz: b2d9c11f9848feb81f5ccf1b22933e84a5a413abb8fc2133854c6a46c8f362bb31da6afb544c95500181b19127efba41662ba915cd639d9d71acfe2c2321d52d
data/README.md CHANGED
@@ -0,0 +1,127 @@
1
+ ## Pinball [![Build Status](https://travis-ci.org/zhulik/pinball.svg?branch=master)](https://travis-ci.org/zhulik/pinball) [![Coverage Status](https://img.shields.io/coveralls/zhulik/pinball.svg)](https://coveralls.io/r/zhulik/pinball?branch=master) [![Code Climate](https://codeclimate.com/github/zhulik/pinball.png)](https://codeclimate.com/github/zhulik/pinball)
2
+
3
+ ### Simple IOC Container and DI tool for ruby.
4
+
5
+ Pinball is a library for using dependency injection within Ruby
6
+ applications. It provides a clear IOC Container that manages
7
+ dependencies between your classes.
8
+
9
+ # Features
10
+
11
+ * Stores objects, classes(as factories) and blocks
12
+ * Can inject dependencies to classes and instances
13
+ * Simple DSL for configuring the container
14
+ * Stored block will be call in dependent class instance
15
+ * You can describe any context-dependent code in blocks
16
+
17
+ ## Usage
18
+
19
+ ### Class injection
20
+
21
+ Consider a `Service` class that has a dependency on a `Repository`. We would
22
+ like this dependency to be available to the service when it is created.
23
+
24
+ First we create a container object and declare the dependencies.
25
+
26
+ ```ruby
27
+ require 'pinball'
28
+
29
+ Pinball::Container.configure do
30
+ define :repository, Repository
31
+ end
32
+ ```
33
+
34
+ Then we declare the `repository` dependency in the Service class by
35
+ using the `inject` declaration.
36
+
37
+ ```ruby
38
+ class Service
39
+ inject :repository
40
+ end
41
+ ```
42
+
43
+ Now we can instantiate Service object and `repository` method will
44
+ be already accessible in it's constructor! In this case *repository*
45
+ method will return the instance of Repository.
46
+ **Notice:** each call of `repository` will create new instance of `Repository`.
47
+
48
+ ### Object injection
49
+
50
+ Also you can inject any already existed object
51
+
52
+ ```ruby
53
+ require 'pinball'
54
+
55
+ Pinball::Container.configure do
56
+ define :string, 'any pre-defined string'
57
+ end
58
+ ```
59
+
60
+ In this case `string` method will return 'any pre-defined string'
61
+
62
+ ### Block injection
63
+
64
+ The most powerful feature of pinball is block injection.
65
+ For example, you have `FirstService` class, that dependent on
66
+ `SecondService` class, but for instantiating `SecondService` you need
67
+ to pass `@current_user` from `FirstService` to it's constructor:
68
+
69
+ ```ruby
70
+ class FirstService
71
+ inject :second_service
72
+
73
+ def initialize(current_user)
74
+ @current_user = current_user
75
+ end
76
+ end
77
+
78
+ class SecondService
79
+ def initialize(current_user)
80
+ @current_user = current_user
81
+ end
82
+ end
83
+ ```
84
+
85
+ Simple defining of `SecondService` dependency will not work here.
86
+ So we can define dependency with a block:
87
+
88
+ ```ruby
89
+ Pinball::Container.configure do
90
+ define :second_service do
91
+ SecondService.new(@current_user)
92
+ end
93
+ end
94
+ ```
95
+
96
+ This block will be executed it `FirstService` instance context where
97
+ `@current_user` will be accessible.
98
+ **Notice:** each call of `second_service` will call this block over and over again.
99
+
100
+ ### class_inject
101
+
102
+ Sometimes you need to inject dependency to class, when it must be available in
103
+ class methods. For this purpose Pinball has `class_inject` declaration:
104
+
105
+ ```ruby
106
+ class Foo
107
+ class_inject :baz
108
+ end
109
+
110
+ Foo.baz
111
+ ```
112
+
113
+ ## Future plans
114
+
115
+ * Rails integration
116
+ * Dependency lifecycle managing in Rails context
117
+ * Smart caching
118
+
119
+ ## Contributing
120
+
121
+ 1. Fork it
122
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
123
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
124
+ 4. Push to the branch (`git push origin my-new-feature`)
125
+ 5. Create new Pull Request
126
+
127
+ Inspired by [Encase gem](https://github.com/dsawardekar/encase "Encase gem")
data/lib/pinball/class.rb CHANGED
@@ -21,6 +21,7 @@ class Class
21
21
  def check_pinball
22
22
  unless self.is_a? Pinball
23
23
  self.extend Pinball
24
+ self.send(:include, Pinball::Methods)
24
25
  end
25
26
  end
26
27
  end
@@ -44,7 +44,7 @@ module Pinball
44
44
  def inject(target)
45
45
  target.class.dependencies.each do |dep|
46
46
  target.define_singleton_method dep do
47
- Container.instance.items[dep].fetch(self)
47
+ Container.instance.items.merge(overridden_dependencies)[dep].fetch(self)
48
48
  end
49
49
  end
50
50
  end
@@ -1,3 +1,3 @@
1
1
  module Pinball
2
- VERSION = '0.0.2'
2
+ VERSION = '0.0.3'
3
3
  end
data/lib/pinball.rb CHANGED
@@ -3,14 +3,24 @@ require 'pinball/container'
3
3
  require 'pinball/class'
4
4
 
5
5
  module Pinball
6
+ module Methods
7
+ attr_reader :overridden_dependencies
8
+
9
+ def override_dependency(key, value = nil, &block)
10
+ @overridden_dependencies[key] = ContainerItem.new(value || block)
11
+ Container.instance.inject(self)
12
+ self
13
+ end
14
+ end
15
+
16
+ attr_reader :dependencies
17
+
18
+
6
19
  def new(*args)
7
20
  object = allocate
8
21
  Container.instance.inject(object)
9
22
  object.send(:initialize, *args)
23
+ object.instance_variable_set(:@overridden_dependencies, {})
10
24
  object
11
25
  end
12
-
13
- def dependencies
14
- @dependencies
15
- end
16
26
  end
@@ -45,4 +45,25 @@ describe Class do
45
45
  expect(foo.baz).to eq(0)
46
46
  end
47
47
  end
48
+
49
+ describe '#override_dependency' do
50
+ let!(:foo_instance) { foo.inject :baz ; foo.new }
51
+
52
+ subject { foo_instance.override_dependency(:baz, 1) }
53
+
54
+ it 'adds overridden dependency' do
55
+ subject
56
+ expect(foo_instance.overridden_dependencies[:baz]).not_to be_nil
57
+ #expect(foo_instance.baz).to eq(1)
58
+ end
59
+
60
+ it 'resolves overridden dependency' do
61
+ subject
62
+ expect(foo_instance.baz).to eq(1)
63
+ end
64
+
65
+ it 'returns self' do
66
+ expect(subject).to eq(foo_instance)
67
+ end
68
+ end
48
69
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pinball
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gleb Sinyavsky
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-05-09 00:00:00.000000000 Z
11
+ date: 2014-05-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler