jerry 1.0.1 → 2.0.0
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 +4 -4
- data/.gitignore +1 -2
- data/.reek +2 -0
- data/.rubocop.yml +4 -0
- data/.travis.yml +11 -2
- data/.yardopts +8 -1
- data/Gemfile +0 -2
- data/Guardfile +16 -0
- data/README.md +93 -78
- data/Rakefile +20 -1
- data/bin/console +3 -0
- data/bin/guard +3 -0
- data/bin/rake +3 -0
- data/bin/setup +3 -0
- data/doc/multiple-configurations.md +51 -0
- data/jerry.gemspec +8 -3
- data/lib/jerry/class_provider.rb +30 -0
- data/lib/jerry/config.rb +64 -61
- data/lib/jerry/errors.rb +16 -0
- data/lib/jerry/version.rb +1 -1
- data/lib/jerry.rb +27 -39
- data/spec/class_provider_spec.rb +109 -0
- data/spec/config_spec.rb +152 -132
- data/spec/error_spec.rb +23 -0
- data/spec/examples_spec.rb +120 -0
- data/spec/fixtures/db_app.rb +17 -0
- data/spec/fixtures/house.rb +15 -0
- data/spec/fixtures/multi_db_app.rb +31 -0
- data/spec/fixtures/shopping_cart.rb +70 -0
- data/spec/fixtures/shopping_cart_config.rb +27 -0
- data/spec/jerry_spec.rb +45 -110
- data/spec/spec_helper.rb +3 -5
- metadata +117 -9
- data/spec/support/silence_warnings.rb +0 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0d97c357a390c069b18e9516ad1e5dac1fcdfea5
|
4
|
+
data.tar.gz: b33040e60cc83f2a481d0181c809e7b045ca96ec
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: eae3155f70ebb6bfd88cd878f2e4dfbe95f042a23439504d185717dd4f20583ffe3ad209e65511d922be4a5e403af7a836ef1969cdd45bff8241685e064838b0
|
7
|
+
data.tar.gz: f4cb19e8c591ae15611d0d02e1d7c6a46ea9fb1071ef37a83e454d48622565f537f59b44f7d67bc7be13ef9c13453cb8010d0a5fc66d4639000863f817f394d8
|
data/.gitignore
CHANGED
@@ -20,7 +20,7 @@ build/
|
|
20
20
|
## Documentation cache and generated files:
|
21
21
|
/.yardoc/
|
22
22
|
/_yardoc/
|
23
|
-
/doc/
|
23
|
+
/html-doc/
|
24
24
|
/rdoc/
|
25
25
|
|
26
26
|
## Environment normalisation:
|
@@ -35,4 +35,3 @@ Gemfile.lock
|
|
35
35
|
|
36
36
|
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
|
37
37
|
.rvmrc
|
38
|
-
|
data/.reek
ADDED
data/.rubocop.yml
ADDED
data/.travis.yml
CHANGED
data/.yardopts
CHANGED
data/Gemfile
CHANGED
data/Guardfile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
guard 'rake', task: 'default' do
|
2
|
+
watch 'Rakefile'
|
3
|
+
watch '.rspec'
|
4
|
+
watch '.rubocop.yml'
|
5
|
+
watch '.reek'
|
6
|
+
watch %r{^lib/}
|
7
|
+
watch %r{^spec/}
|
8
|
+
end
|
9
|
+
|
10
|
+
guard 'rake', task: 'doc' do
|
11
|
+
watch '.yardopts'
|
12
|
+
watch 'LICENSE.txt'
|
13
|
+
watch(/.+\.(md|markdown)/)
|
14
|
+
watch %r{^lib/}
|
15
|
+
watch %r{^doc/}
|
16
|
+
end
|
data/README.md
CHANGED
@@ -4,114 +4,129 @@ Jerry
|
|
4
4
|
[](https://travis-ci.org/beraboris/jerry)
|
5
5
|
[](https://coveralls.io/r/beraboris/jerry)
|
6
6
|
|
7
|
-
Jerry
|
8
|
-
|
7
|
+
Jerry is a Ruby
|
8
|
+
[Inversion of Control](https://en.wikipedia.org/wiki/Inversion_of_control)
|
9
|
+
container. You tell it how your classes depend on one another and it will create
|
10
|
+
your application and wire all the dependencies correctly.
|
9
11
|
|
10
|
-
|
11
|
-
|
12
|
+
Jerry aims to be simple and straight forward. It also aims to be out of your
|
13
|
+
way. Your classes don't need to know anything about jerry.
|
12
14
|
|
13
|
-
|
15
|
+
Why?
|
16
|
+
----
|
14
17
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
+
[Dependency Injection](https://en.wikipedia.org/wiki/Dependency_injection) is a
|
19
|
+
great pattern for building loosely coupled applications. It allows you to build
|
20
|
+
isolated components that can be swapped around.
|
18
21
|
|
19
|
-
|
22
|
+
The problem with this pattern is that it leaves you with a bunch of classes that
|
23
|
+
you have to build and wire together yourself. Jerry does that for you.
|
20
24
|
|
21
|
-
|
25
|
+
Getting started
|
26
|
+
---------------
|
22
27
|
|
23
|
-
|
24
|
-
|
25
|
-
$ gem install jerry
|
28
|
+
### Important note
|
26
29
|
|
27
|
-
|
28
|
-
|
30
|
+
Currently jerry only supports constructor injection. If you're hoping to use
|
31
|
+
setter injection, you're out of luck. You're going to need to switch to
|
32
|
+
constructor injection.
|
29
33
|
|
30
|
-
|
34
|
+
### Install it
|
31
35
|
|
32
|
-
|
33
|
-
class Window; end
|
34
|
-
class Door; end
|
35
|
-
|
36
|
-
class House
|
37
|
-
attr_reader :window, :door
|
38
|
-
|
39
|
-
def initialize(window, door)
|
40
|
-
@window = window
|
41
|
-
@door = door
|
42
|
-
end
|
43
|
-
end
|
44
|
-
```
|
36
|
+
You have 3 options:
|
45
37
|
|
46
|
-
|
38
|
+
Options 1: Add jerry to your `Gemfile`
|
47
39
|
|
48
40
|
```ruby
|
49
|
-
|
41
|
+
gem 'jerry', '~> 2.0'
|
50
42
|
```
|
51
|
-
|
52
|
-
|
43
|
+
|
44
|
+
Option 2: Add jerry to your `*.gemspec`
|
53
45
|
|
54
46
|
```ruby
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
component(:house) { House.new rig(:window), rig(:door) }
|
47
|
+
Gem::Specification.new do |spec|
|
48
|
+
# ...
|
49
|
+
spec.add_dependency 'jerry', '~> 2.0'
|
59
50
|
end
|
60
51
|
```
|
61
52
|
|
62
|
-
|
63
|
-
build a component.
|
53
|
+
Option 3: Just install it
|
64
54
|
|
65
|
-
|
55
|
+
$ gem install jerry
|
56
|
+
|
57
|
+
### Create a configuration class
|
66
58
|
|
67
59
|
```ruby
|
68
|
-
jerry
|
69
|
-
house = jerry.rig :house
|
70
|
-
```
|
60
|
+
require 'jerry'
|
71
61
|
|
72
|
-
|
73
|
-
|
62
|
+
class MyConfig < Jerry::Config
|
63
|
+
def initialize(foo_db_url, bar_db_url)
|
64
|
+
@foo_db_url = foo_db_url
|
65
|
+
@bar_db_url = bar_db_url
|
66
|
+
end
|
74
67
|
|
75
|
-
|
76
|
-
`:single`. If you set the scope to `:single` only one instance of the component will be created. If you set it to
|
77
|
-
`:instance`, a new instance of the component will be created each time you call `rig`.
|
68
|
+
bind Application, [FooService, BarService]
|
78
69
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
70
|
+
singleton bind FooService, [BarService, :foo_db]
|
71
|
+
singleton bind BarService, [:bar_db]
|
72
|
+
|
73
|
+
named_bind :foo_db Database [proc { @foo_db_url }]
|
74
|
+
named_bind :bar_db Database [proc { @bar_db_url }]
|
83
75
|
end
|
84
|
-
|
76
|
+
```
|
85
77
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
78
|
+
Let's go over what's going on in this configuration class.
|
79
|
+
|
80
|
+
First, we define a constructor. It takes two database urls and stores them as
|
81
|
+
instance variables. We'll go over what these urls are used for later. You should
|
82
|
+
note that this constructor has no special meaning to jerry. It's entirely
|
83
|
+
specific to this configuration class.
|
84
|
+
|
85
|
+
Second, we use `bind` to tell jerry how to wire the `Application` class. `bind`
|
86
|
+
takes two arguments. The first is the class we're telling jerry about and the
|
87
|
+
second is an array that tells jerry what constructor arguments to pass to the
|
88
|
+
class. Here you can notice that `Application` takes an instance of `FooService`
|
89
|
+
and an instance of `BarService` in its constructor.
|
90
|
+
|
91
|
+
Third, we tell jerry how to build `FooService` and `BarService`. Note that we're
|
92
|
+
calling `singleton bind` instead of `bind` here. `singleton` is used to tell
|
93
|
+
jerry that we want it to only instantiate the class we just described only once.
|
94
|
+
When we use `singleton` jerry will always pass the same instance of the given
|
95
|
+
class as a constructor argument. This is useful when some of your classes have
|
96
|
+
a persistent state. In this case, the `BarService` instance passed to both
|
97
|
+
`Application` and `FooService` will be the exact same instance.
|
98
|
+
|
99
|
+
Finally, we tell jerry how to build two instances of the `Database` class. The
|
100
|
+
first instance is named `:foo_db` and the second is named `:bar_db`. We
|
101
|
+
reference these instances when telling jerry about `FooService` and
|
102
|
+
`BarService`. This is what `named_bind` is for. We should also note that the
|
103
|
+
last arguments of the `named_bind` calls each contain a proc. In this case, the
|
104
|
+
procs are used to inject the database urls for each database. In a more general
|
105
|
+
sense, the procs are used to pass settings to various classes.
|
106
|
+
|
107
|
+
### Create your application
|
90
108
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
109
|
+
```ruby
|
110
|
+
require 'jerry'
|
111
|
+
|
112
|
+
jerry = Jerry.new MyConfig.new('db://localhost/foo', 'db://localhost/bar')
|
113
|
+
app = jerry[Application]
|
95
114
|
```
|
96
115
|
|
97
|
-
|
98
|
-
----------------
|
116
|
+
Let's look at what's going on here.
|
99
117
|
|
100
|
-
|
101
|
-
|
118
|
+
First, we create an instance of our configuration class. We pass the urls for
|
119
|
+
our two databases to the constructor.
|
102
120
|
|
103
|
-
|
104
|
-
|
121
|
+
Second, we create an instance of `Jerry` passing in the instance of our
|
122
|
+
configuration class.
|
105
123
|
|
106
|
-
|
107
|
-
|
108
|
-
component(:thing) { "from a" }
|
109
|
-
end
|
110
|
-
class ConfB < Jerry::Config
|
111
|
-
component(:thing) { "from b" }
|
112
|
-
end
|
113
|
-
jerry = Jerry.new ConfA.new, ConfB.new
|
124
|
+
Finally, we use the square bracket operator (`[]`) to create an instance of our
|
125
|
+
application. Of course our application is wired properly.
|
114
126
|
|
115
|
-
|
116
|
-
|
117
|
-
|
127
|
+
Learn more
|
128
|
+
----------
|
129
|
+
|
130
|
+
If you'd like to learn more, here's some more documentation:
|
131
|
+
|
132
|
+
- [Multiple configurations](doc/multiple-configurations.md)
|
data/Rakefile
CHANGED
@@ -1,5 +1,24 @@
|
|
1
1
|
require 'bundler/gem_tasks'
|
2
2
|
require 'rspec/core/rake_task'
|
3
|
+
require 'yard'
|
4
|
+
require 'rubocop/rake_task'
|
5
|
+
require 'reek/rake/task'
|
6
|
+
|
7
|
+
task default: [:spec, :lint]
|
3
8
|
|
4
9
|
RSpec::Core::RakeTask.new :spec
|
5
|
-
|
10
|
+
YARD::Rake::YardocTask.new :doc
|
11
|
+
|
12
|
+
task lint: [:reek, :rubocop]
|
13
|
+
|
14
|
+
desc 'Run rubocop linter on lib/**/*.rb and spec/**/*.rb'
|
15
|
+
RuboCop::RakeTask.new :rubocop do |t|
|
16
|
+
t.patterns = ['lib/**/*.rb', 'spec/**/*.rb']
|
17
|
+
t.fail_on_error = false
|
18
|
+
end
|
19
|
+
|
20
|
+
desc 'Run reek linter on lib/**/*.rb'
|
21
|
+
Reek::Rake::Task.new :reek do |t|
|
22
|
+
t.source_files = 'lib/**/*.rb'
|
23
|
+
t.fail_on_error = false
|
24
|
+
end
|
data/bin/console
ADDED
data/bin/guard
ADDED
data/bin/rake
ADDED
data/bin/setup
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
Multiple configurations
|
2
|
+
-----------------------
|
3
|
+
|
4
|
+
Jerry allows you to define and use multiple configurations. This way you can
|
5
|
+
separate the dependency configurations for different parts of your application.
|
6
|
+
|
7
|
+
Let's look at an example. In this example, we have a simple on-line store. It
|
8
|
+
has users, products and shopping carts. We can create separate configurations
|
9
|
+
for user, product, and shopping cart related classed. Users, products and
|
10
|
+
shopping carts each have a service that talks to the database and other services
|
11
|
+
and a controller that talks to the service. Here's what it might look like:
|
12
|
+
|
13
|
+
```ruby
|
14
|
+
class DatabaseConfig < Jerry::Config
|
15
|
+
# database connector thingy
|
16
|
+
bind Database
|
17
|
+
end
|
18
|
+
|
19
|
+
class UserConfig < Jerry::Config
|
20
|
+
bind UserService, [Database]
|
21
|
+
bind UserController, [UserService]
|
22
|
+
end
|
23
|
+
|
24
|
+
class ProductConfig < Jerry::Config
|
25
|
+
bind ProductService, [Database]
|
26
|
+
bind ProductController, [ProductService]
|
27
|
+
end
|
28
|
+
|
29
|
+
class ShoppingCartConfig < Jerry::Config
|
30
|
+
bind ShoppingCartService, [Database, ProductService, UserService]
|
31
|
+
bind ShoppingCartController, [ShoppingCartService]
|
32
|
+
end
|
33
|
+
|
34
|
+
class AppConfig < Jerry::Config
|
35
|
+
bind Application, [UserController, ProductController, ShoppingCartController]
|
36
|
+
end
|
37
|
+
|
38
|
+
jerry = Jerry.new(
|
39
|
+
DatabaseConfig.new,
|
40
|
+
AppConfig.new,
|
41
|
+
UserConfig.new,
|
42
|
+
ProductConfig.new,
|
43
|
+
ShoppingCartConfig.new
|
44
|
+
)
|
45
|
+
|
46
|
+
app = jerry[Application]
|
47
|
+
```
|
48
|
+
|
49
|
+
Note that in the example above, some the configurations reference classes that
|
50
|
+
are configured in other configurations. This is perfectly fine. When
|
51
|
+
instantiating a class, jerry will look at all the configurations.
|
data/jerry.gemspec
CHANGED
@@ -14,12 +14,17 @@ Gem::Specification.new do |spec|
|
|
14
14
|
spec.license = 'MIT'
|
15
15
|
|
16
16
|
spec.files = `git ls-files -z`.split("\x0")
|
17
|
-
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
17
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
18
|
spec.require_paths = ['lib']
|
20
19
|
|
21
20
|
spec.add_development_dependency 'bundler', '~> 1.6'
|
22
21
|
spec.add_development_dependency 'rake'
|
23
|
-
spec.add_development_dependency '
|
24
|
-
spec.add_development_dependency '
|
22
|
+
spec.add_development_dependency 'guard'
|
23
|
+
spec.add_development_dependency 'guard-rake'
|
24
|
+
spec.add_development_dependency 'rspec', '~> 3.3'
|
25
|
+
spec.add_development_dependency 'coveralls', '~> 0.8'
|
26
|
+
spec.add_development_dependency 'yard', '~> 0.8.7'
|
27
|
+
spec.add_development_dependency 'pry', '~> 0.10'
|
28
|
+
spec.add_development_dependency 'rubocop', '~> 0.32'
|
29
|
+
spec.add_development_dependency 'reek', '~> 2.2'
|
25
30
|
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
class Jerry
|
2
|
+
# A provider that instanciates a given class by collecting constructor
|
3
|
+
# arguments through a given jerry instance.
|
4
|
+
class ClassProvider
|
5
|
+
# @param klass [Class] class to be instanciated
|
6
|
+
# @param args_spec [Array<Clsss, Symbol, Proc>] specification for the
|
7
|
+
# constructor arguments. Classes and Symbols are used to collect the
|
8
|
+
# arguments from the jerry instance. Procs are called to generate
|
9
|
+
# arguments.
|
10
|
+
def initialize(klass, args_spec)
|
11
|
+
@klass = klass
|
12
|
+
@args_spec = args_spec
|
13
|
+
end
|
14
|
+
|
15
|
+
# @param jerry [Jerry] a jerry instance
|
16
|
+
# @param config [Jerry::Config] the config holding the provider
|
17
|
+
# @return An instance of the class given in the constructor
|
18
|
+
def call(jerry, config)
|
19
|
+
args = @args_spec.map do |spec|
|
20
|
+
if spec.respond_to? :call
|
21
|
+
config.instance_exec(jerry, config, &spec)
|
22
|
+
else
|
23
|
+
jerry[spec]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
@klass.new(*args)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/lib/jerry/config.rb
CHANGED
@@ -1,85 +1,88 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
class ComponentError < StandardError; end
|
1
|
+
require 'jerry/class_provider'
|
2
|
+
require 'jerry/errors'
|
4
3
|
|
5
|
-
|
4
|
+
class Jerry
|
5
|
+
# A configuration specifies how to wire parts of an application
|
6
|
+
#
|
7
|
+
# @abstract Subclass this class in order to create a configuration
|
8
|
+
# @example Basic usage
|
9
|
+
# class Door; end
|
10
|
+
# class Window; end
|
6
11
|
#
|
7
|
-
#
|
8
|
-
#
|
12
|
+
# class House
|
13
|
+
# def initialize(door, window)
|
14
|
+
# # ...
|
15
|
+
# end
|
16
|
+
# end
|
9
17
|
#
|
10
|
-
# @abstract Subclass to define a config
|
11
|
-
# @example
|
12
18
|
# class MyConfig < Jerry::Config
|
13
|
-
#
|
14
|
-
#
|
19
|
+
# bind House, [Door, Window]
|
20
|
+
# bind Door
|
21
|
+
# bind Window
|
15
22
|
# end
|
16
23
|
class Config
|
17
24
|
class << self
|
18
|
-
#
|
19
|
-
|
20
|
-
|
25
|
+
# Specify how to wire the dependencies of a given class
|
26
|
+
#
|
27
|
+
# @param klass [Class] The class to wire the dependencies for
|
28
|
+
# @param ctor_args [Array<Class, Symbol, Proc>] specifies the arguments to
|
29
|
+
# be given to the constructor
|
30
|
+
# @return [Class] the class that will be instanciated
|
31
|
+
def bind(klass, ctor_args = [])
|
32
|
+
named_bind klass, klass, ctor_args
|
21
33
|
end
|
22
34
|
|
23
|
-
#
|
35
|
+
# Specify how to wire the dependencies of a given class giving it a name
|
24
36
|
#
|
25
|
-
# @param [Symbol]
|
26
|
-
#
|
27
|
-
# @
|
28
|
-
#
|
29
|
-
#
|
30
|
-
#
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
37
|
+
# @param name [Symbol] The name used to identify this way of building the
|
38
|
+
# given class
|
39
|
+
# @param klass [Class] The class to wire the dependencies for
|
40
|
+
# @param ctor_args [Array<Class, Symbol, Proc>] specifies the arguments to
|
41
|
+
# be given to the constructor
|
42
|
+
# @return [Symbol] the name of the class that will be instanciated
|
43
|
+
def named_bind(name, klass, ctor_args = [])
|
44
|
+
providers[name] = ClassProvider.new klass, ctor_args
|
45
|
+
name
|
46
|
+
end
|
35
47
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
48
|
+
# Specifies that a class should only be instanciated once
|
49
|
+
#
|
50
|
+
# @param key [Class, Symbol] the class or the name of the class that
|
51
|
+
# should only be instanciated once
|
52
|
+
def singleton(key)
|
53
|
+
return unless providers.key? key
|
40
54
|
|
41
|
-
|
42
|
-
case scope
|
43
|
-
when :single
|
44
|
-
cache[name] ||= instance_eval(&block)
|
45
|
-
when :instance
|
46
|
-
instance_eval(&block)
|
47
|
-
end
|
48
|
-
end
|
55
|
+
provider = providers[key]
|
49
56
|
|
50
|
-
|
57
|
+
instance = nil
|
58
|
+
providers[key] = ->(*args) { instance ||= provider.call(*args) }
|
51
59
|
end
|
52
|
-
end
|
53
60
|
|
54
|
-
|
55
|
-
|
56
|
-
|
61
|
+
def providers
|
62
|
+
@providers ||= {}
|
63
|
+
end
|
57
64
|
end
|
58
65
|
|
59
|
-
#
|
60
|
-
#
|
61
|
-
# This gets set by Jerry when it loads a config
|
66
|
+
# The jerry instance this config is part of
|
62
67
|
attr_writer :jerry
|
63
68
|
|
64
|
-
|
69
|
+
# @return an instance of an object wired by the config
|
70
|
+
def [](key)
|
71
|
+
provider = self.class.providers[key]
|
65
72
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
#
|
75
|
-
# This should be used inside the block passed to Config::component
|
76
|
-
def knows?(component)
|
77
|
-
@jerry.knows? component
|
73
|
+
if provider
|
74
|
+
provider.call @jerry, self
|
75
|
+
else
|
76
|
+
fail InstantiationError,
|
77
|
+
"Failed to instanciate #{key}. Can't find provider for it"
|
78
|
+
end
|
79
|
+
rescue RuntimeError
|
80
|
+
raise InstantiationError, "Provider for #{key} raised an error"
|
78
81
|
end
|
79
82
|
|
80
|
-
#
|
81
|
-
def
|
82
|
-
|
83
|
+
# @return true if this config can provide the given key, false otherwise
|
84
|
+
def knows?(key)
|
85
|
+
self.class.providers.key? key
|
83
86
|
end
|
84
87
|
end
|
85
|
-
end
|
88
|
+
end
|
data/lib/jerry/errors.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'English'
|
2
|
+
|
3
|
+
class Jerry
|
4
|
+
# Base error class for Jerry that allows recording causing exceptions
|
5
|
+
class Error < RuntimeError
|
6
|
+
attr_reader :cause
|
7
|
+
|
8
|
+
def initialize(message = nil)
|
9
|
+
super
|
10
|
+
@cause = $ERROR_INFO
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
# Failed to instanciate a class
|
15
|
+
class InstantiationError < Jerry::Error; end
|
16
|
+
end
|
data/lib/jerry/version.rb
CHANGED