config_plus 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.ja.md +137 -0
- data/README.md +146 -0
- data/lib/config_plus.rb +8 -0
- data/lib/config_plus/base.rb +83 -0
- data/lib/config_plus/config.rb +33 -0
- data/lib/config_plus/default_loader_logic.rb +31 -0
- data/lib/config_plus/helper.rb +39 -0
- data/lib/config_plus/loader.rb +37 -0
- data/lib/config_plus/merger.rb +23 -0
- data/lib/config_plus/node.rb +51 -0
- data/lib/config_plus/version.rb +3 -0
- metadata +69 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 20890e554dc232e7ec1a72414f746b15ac7a3449
|
4
|
+
data.tar.gz: efacb601ce0541c0e2141e6846bede15ab2cb437
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: fb3a6f9ec6260f0ed6299053898d1638219d9a1146c9e117f5c28b8708d74abc1853fd4395ff1b531eeaae23dea1b86ba9dd7391e7503018ec9152047c9b52f4
|
7
|
+
data.tar.gz: 48713b64f82b3b38a8b3c486af64fa34e9ef38732ebebd091ef591384d1d9392ae6bff0cc8f737ff7e51b3de2cecbded7cd11b545860ab92582f50af05d1c650
|
data/README.ja.md
ADDED
@@ -0,0 +1,137 @@
|
|
1
|
+
ConfigPlus
|
2
|
+
==================================================
|
3
|
+
|
4
|
+
`ConfigPlus` は YAML ファイルから設定情報を読み込むためのライブラリです。
|
5
|
+
読み込みたい YAML ファイルのパスを指定すると、`ConfigPlus.root` から設定情報にアクセスできるようになります。
|
6
|
+
|
7
|
+
基本的な使用例
|
8
|
+
--------------------------------------------------
|
9
|
+
例として、次のような YAML ファイルがあるとすると、
|
10
|
+
|
11
|
+
```yaml
|
12
|
+
foo:
|
13
|
+
baa:
|
14
|
+
baz:
|
15
|
+
spam: 123
|
16
|
+
ham: abc
|
17
|
+
```
|
18
|
+
|
19
|
+
次のようにアクセスできます。
|
20
|
+
|
21
|
+
```ruby
|
22
|
+
ConfigPlus.generate(from: '/path/to/configuration/file.yml')
|
23
|
+
ConfigPlus.root[:foo][:baa][:baz]
|
24
|
+
#=> {"spam"=>123, "ham"=>"abc"}
|
25
|
+
|
26
|
+
ConfigPlus.root['foo']['baa']['baz']
|
27
|
+
#=> {"spam"=>123, "ham"=>"abc"}
|
28
|
+
|
29
|
+
ConfigPlus.root.foo.baa.baz
|
30
|
+
#=> {"spam"=>123, "ham"=>"abc"}
|
31
|
+
|
32
|
+
ConfigPlus.root.get('foo.baa.baz')
|
33
|
+
#=> {"spam"=>123, "ham"=>"abc"}
|
34
|
+
```
|
35
|
+
|
36
|
+
メソッド風のアクセスには多少の制限があります。
|
37
|
+
キーがメソッド名として有効である必要があるのはもちろんのこと、private
|
38
|
+
メソッドも含めて既存のメソッド名と重複した場合は、既存のメソッドの方が有効になります。
|
39
|
+
|
40
|
+
`ConfigPlus.root` は `Hash` を拡張したオブジェクトなので、
|
41
|
+
おおよそ `Hash` のメソッドを上書きできない(正確には `ConfigPlus::Node`
|
42
|
+
のメソッドを上書きできない)、ということになります。
|
43
|
+
|
44
|
+
自動マッピング
|
45
|
+
--------------------------------------------------
|
46
|
+
YAML の構造と同じパスを持つクラス(上記の場合であれば `Foo::Baa::Baz` というクラス)がある場合、
|
47
|
+
次のようにして設定情報にアクセスすることもできます。
|
48
|
+
|
49
|
+
```ruby
|
50
|
+
module Foo
|
51
|
+
module Baa
|
52
|
+
class Baz
|
53
|
+
include ConfigPlus
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
Foo::Baa::Baz.config
|
59
|
+
#=> {"spam"=>123, "ham"=>"abc"}
|
60
|
+
|
61
|
+
Foo::Baa::Baz.config.spam
|
62
|
+
#=> 123
|
63
|
+
|
64
|
+
baz = Foo::Baa::Baz.new
|
65
|
+
baz.config.ham
|
66
|
+
#=> "abc"
|
67
|
+
```
|
68
|
+
|
69
|
+
`ConfigPlus` を `include` することで、クラスメソッドとインスタンスメソッドに
|
70
|
+
`config` というメソッドが追加されます(このメソッド名は設定で変更できます)。
|
71
|
+
そこから、読み込んだ設定情報にアクセスできるようになります。
|
72
|
+
|
73
|
+
上書きマージ
|
74
|
+
--------------------------------------------------
|
75
|
+
`ConfigPlus` に読み込ませるパスには、ディレクトリを指定することもできます。
|
76
|
+
ディレクトリを指定した場合は、サブディレクトリも含めてファイルが探索され、
|
77
|
+
その中から拡張子がマッチしたものが全て読み込まれます。
|
78
|
+
読み込まれた YAML は、最終的に一つにマージされた Hash となります。
|
79
|
+
|
80
|
+
設定ファイルはファイル名でソートされた上で読み込まれ、マージされます。
|
81
|
+
このため、同じ設定情報があればソート順の大きい方で上書きされます。
|
82
|
+
|
83
|
+
例として、次のようなファイルが同じディレクトリに配置されていたとすると、
|
84
|
+
|
85
|
+
```yml
|
86
|
+
# sample-00.yml
|
87
|
+
sample:
|
88
|
+
setting_a:
|
89
|
+
spam: spam-00
|
90
|
+
ham: ham-00
|
91
|
+
egg: egg-00
|
92
|
+
```
|
93
|
+
|
94
|
+
```yml
|
95
|
+
# sample-01.yml
|
96
|
+
sample:
|
97
|
+
setting_a:
|
98
|
+
ham: ham-01
|
99
|
+
```
|
100
|
+
|
101
|
+
`sample-00.yml` がベースとなり、そこに `sample-01.yml` が上書きされて読み込まれます。
|
102
|
+
|
103
|
+
```ruby
|
104
|
+
Sample::SettingA.config
|
105
|
+
#=> {"spam"=>"spam-00", "ham"=>"ham-01", "egg"=>"egg-00"}
|
106
|
+
```
|
107
|
+
|
108
|
+
その他
|
109
|
+
--------------------------------------------------
|
110
|
+
`ConfigPlus` の動作は設定で変更できます。
|
111
|
+
設定ファイルへのパス以外の設定がある場合、次のようにブロックを使って記述します。
|
112
|
+
|
113
|
+
```ruby
|
114
|
+
ConfigPlus.configure do |conf|
|
115
|
+
conf.root_dir = Rails.root
|
116
|
+
conf.source = 'config/config_plus'
|
117
|
+
conf.config_method = :setting
|
118
|
+
conf.extension = '00.yml'
|
119
|
+
conf.namespace = Rails.env
|
120
|
+
end
|
121
|
+
```
|
122
|
+
|
123
|
+
`configure` メソッドは `generate` とほぼ同じ処理をするので、上記のように書けば改めて `generate` する必要はありません。
|
124
|
+
|
125
|
+
主な設定を簡単に説明すると、次のようになります。
|
126
|
+
|
127
|
+
| 設定 | 概要説明 | 初期値 |
|
128
|
+
| --------------- | -------------------------------------------------------------------- | ----------------- |
|
129
|
+
| `config_method` | `include ConfigPlus` で自動マッピングした際の設定読み込みメソッド名 | `config` |
|
130
|
+
| `extension` | 読み込むファイルの拡張子。`source` がディレクトリの場合に有効 | `['yml', 'yaml']` |
|
131
|
+
| `namespace` | 使用するネームスペース | |
|
132
|
+
| `root_dir` | `source` で指定するパスの親ディレクトリのパス | |
|
133
|
+
| `source` | 設定ファイル、またはそれが格納されているディレクトリのパス | |
|
134
|
+
|
135
|
+
ライセンス
|
136
|
+
--------------------------------------------------
|
137
|
+
`ConfigPlus` は MIT ライセンスです。
|
data/README.md
ADDED
@@ -0,0 +1,146 @@
|
|
1
|
+
ConfigPlus
|
2
|
+
============================================================
|
3
|
+
|
4
|
+
An easy-to-use, powerful configuration module using YAML files
|
5
|
+
for Ruby.
|
6
|
+
|
7
|
+
|
8
|
+
Simple Usage
|
9
|
+
------------------------------------------------------------
|
10
|
+
Add a configuration file in YAML format in your project:
|
11
|
+
|
12
|
+
```yml
|
13
|
+
foo:
|
14
|
+
baa:
|
15
|
+
baz:
|
16
|
+
spam: 123
|
17
|
+
ham: abc
|
18
|
+
```
|
19
|
+
|
20
|
+
You can access the configuration values with `ConfigPlus.root`:
|
21
|
+
|
22
|
+
```ruby
|
23
|
+
ConfigPlus.generate(from: '/path/to/configuration/file.yml')
|
24
|
+
ConfigPlus.root.foo.baa.baz.spam
|
25
|
+
#=> 123
|
26
|
+
|
27
|
+
ConfigPlus.root['foo']['baa']['baz']['spam']
|
28
|
+
#=> 123
|
29
|
+
|
30
|
+
ConfigPlus.root[:foo][:baa][:baz][:spam]
|
31
|
+
#=> 123
|
32
|
+
|
33
|
+
ConfigPlus.root.get('foo.baa.baz.spam')
|
34
|
+
#=> 123
|
35
|
+
```
|
36
|
+
|
37
|
+
`ConfigPlus` recurses a file tree looking for configuration files
|
38
|
+
when you specify a directory path at `ConfigPlus.generate from:`.
|
39
|
+
|
40
|
+
```ruby
|
41
|
+
ConfigPlus.generate(from: '/path/to/configuration/directory')
|
42
|
+
```
|
43
|
+
|
44
|
+
And you can specify some pathes using an array.
|
45
|
+
|
46
|
+
```ruby
|
47
|
+
ConfigPlus.generate(from: ['/path/to/directory1', '/path/to/file1.yml'])
|
48
|
+
```
|
49
|
+
|
50
|
+
|
51
|
+
Auto Mapping
|
52
|
+
------------------------------------------------------------
|
53
|
+
When data structure of loaded YAML and class structure of your
|
54
|
+
Ruby project have the same hierarchy, accessing the configuration
|
55
|
+
can be more simple:
|
56
|
+
|
57
|
+
```yml
|
58
|
+
fizz:
|
59
|
+
buzz:
|
60
|
+
spam: bacon
|
61
|
+
ham: sausage
|
62
|
+
```
|
63
|
+
|
64
|
+
```ruby
|
65
|
+
ConfigPlus.generate(from: '/path/to/configuration/file.yml')
|
66
|
+
|
67
|
+
module Fizz
|
68
|
+
class Buzz
|
69
|
+
include ConfigPlus
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
Fizz::Buzz.config.ham
|
74
|
+
#=> "sausage"
|
75
|
+
|
76
|
+
buzz = Fizz:Buzz.new
|
77
|
+
buzz.config.spam
|
78
|
+
#=> "bacon"
|
79
|
+
```
|
80
|
+
|
81
|
+
|
82
|
+
Overwrite Merge
|
83
|
+
------------------------------------------------------------
|
84
|
+
`ConfigPlus` loads the specified configuration files in file
|
85
|
+
name order and merge all of configuration into a single hash.
|
86
|
+
|
87
|
+
```yml
|
88
|
+
# sample-00.yml
|
89
|
+
|
90
|
+
sample:
|
91
|
+
setting_a:
|
92
|
+
spam: bacon
|
93
|
+
ham: sausage
|
94
|
+
egg: baked beans
|
95
|
+
```
|
96
|
+
|
97
|
+
```yml
|
98
|
+
# sample-01.yml
|
99
|
+
|
100
|
+
sample:
|
101
|
+
setting_a:
|
102
|
+
ham: spam
|
103
|
+
```
|
104
|
+
|
105
|
+
```ruby
|
106
|
+
Sample::SettingA.config
|
107
|
+
#=> {"spam"=>"bacon", "ham"=>"spam", "egg"=>"baked beans"}
|
108
|
+
```
|
109
|
+
|
110
|
+
|
111
|
+
Others
|
112
|
+
------------------------------------------------------------
|
113
|
+
Settings of `ConfigPlus` can be changed by the following way:
|
114
|
+
|
115
|
+
```ruby
|
116
|
+
ConfigPlus.configure do |conf|
|
117
|
+
conf.root_dir = Rails.root
|
118
|
+
conf.source = 'config/config_plus'
|
119
|
+
conf.config_method = :setting
|
120
|
+
conf.extension = [:yml, :yaml]
|
121
|
+
conf.namespace = Rails.env
|
122
|
+
end
|
123
|
+
```
|
124
|
+
|
125
|
+
`configure` method works in a similar way as `generate` method.
|
126
|
+
Properties you can set are following:
|
127
|
+
|
128
|
+
* `config_method`
|
129
|
+
* a method name to access configuration using in a class
|
130
|
+
which does `include ConfigPlus`
|
131
|
+
* `extension`
|
132
|
+
* extensions of configuration files which you allow to be
|
133
|
+
loaded when you specify a directory path as `source`
|
134
|
+
* `namespace`
|
135
|
+
* load configuration only from a tree of which first
|
136
|
+
hierarchy key name is matched with the specified name
|
137
|
+
* `root_dir`
|
138
|
+
* used as a parent directory path when you specify a
|
139
|
+
relative path as `source`
|
140
|
+
* `source`
|
141
|
+
* a file path or a directory path or an array of them
|
142
|
+
|
143
|
+
|
144
|
+
License
|
145
|
+
------------------------------------------------------------
|
146
|
+
MIT License
|
data/lib/config_plus.rb
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
module ConfigPlus
|
2
|
+
class << self
|
3
|
+
attr_reader :root
|
4
|
+
|
5
|
+
# Sets up configuration of ++ConfigPlus++ and loads data
|
6
|
+
#
|
7
|
+
# When a YAML file path is specified with
|
8
|
+
# ++source++ (or ++root_dir++) setting as below,
|
9
|
+
# configuration data would be loaded from the file.
|
10
|
+
#
|
11
|
+
# ConfigPlus.configure do |conf|
|
12
|
+
# conf.source = '/path/to/yaml/file.yml'
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
# When a directory path is specified, configuration
|
16
|
+
# would be loaded from all YAML files under the
|
17
|
+
# specified directory.
|
18
|
+
#
|
19
|
+
def configure
|
20
|
+
yield config if block_given?
|
21
|
+
load
|
22
|
+
end
|
23
|
+
|
24
|
+
# Sets up configuration of ++ConfigPlus++ and loads data
|
25
|
+
#
|
26
|
+
# You can describe the following code, when it needs
|
27
|
+
# only a single file for a resource of ++ConfigPlus++.
|
28
|
+
#
|
29
|
+
# ConfigPlus.generate(from: '/path/to/yaml/file.yml')
|
30
|
+
#
|
31
|
+
def generate(from: nil, **properties)
|
32
|
+
config.source = from if from
|
33
|
+
properties.each do |k, v|
|
34
|
+
attr = "#{k}="
|
35
|
+
config.public_send(attr, v) if config.respond_to? attr
|
36
|
+
end
|
37
|
+
load
|
38
|
+
end
|
39
|
+
|
40
|
+
protected
|
41
|
+
|
42
|
+
def config
|
43
|
+
@config ||= ::ConfigPlus::Config.new
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
# loads a configuration data as a hash object
|
49
|
+
# from files specified with ++source++ or
|
50
|
+
# ++root_dir++ settings.
|
51
|
+
#
|
52
|
+
def load
|
53
|
+
hash = config.loader.load
|
54
|
+
@root = ::ConfigPlus::Node.new(hash)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.included(base)
|
59
|
+
method_name = self.config.config_method
|
60
|
+
return unless method_name
|
61
|
+
variable_name = "@#{method_name}"
|
62
|
+
helper = ::ConfigPlus::Helper
|
63
|
+
own = helper.config_for(base, ::ConfigPlus.root)
|
64
|
+
|
65
|
+
inheritance = base.ancestors.select {|klass|
|
66
|
+
klass != base and
|
67
|
+
klass != ConfigPlus and
|
68
|
+
klass.ancestors.include?(ConfigPlus)
|
69
|
+
}.reverse.each_with_object({}) {|klass, hsh|
|
70
|
+
h = klass.public_send(method_name)
|
71
|
+
h = helper.config_for(klass, ::ConfigPlus.root) unless
|
72
|
+
h or h.is_a?(Hash)
|
73
|
+
hsh.merge!(h)
|
74
|
+
}
|
75
|
+
|
76
|
+
[base, base.singleton_class].each do |obj|
|
77
|
+
obj.instance_eval do
|
78
|
+
config = inheritance ? inheritance.merge(own || {}) : own
|
79
|
+
define_method method_name, -> { config }
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module ConfigPlus
|
2
|
+
class Config
|
3
|
+
attr_accessor :config_method,
|
4
|
+
:extension,
|
5
|
+
:namespace,
|
6
|
+
:root_dir,
|
7
|
+
:source
|
8
|
+
attr_reader :version
|
9
|
+
attr_writer :loader_logic
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
@version = VERSION
|
13
|
+
@config_method = :config
|
14
|
+
@extension = nil
|
15
|
+
@loader_logic = :default
|
16
|
+
@namespace = nil
|
17
|
+
@root_dir = nil
|
18
|
+
@source = nil
|
19
|
+
end
|
20
|
+
|
21
|
+
def loader
|
22
|
+
Loader.new(self)
|
23
|
+
end
|
24
|
+
|
25
|
+
def loader_logic
|
26
|
+
name = @loader_logic.to_s.capitalize
|
27
|
+
name = "#{name}LoaderLogic"
|
28
|
+
raise "Unknown loader logic named `#{name}'" unless
|
29
|
+
ConfigPlus::const_defined?(name)
|
30
|
+
ConfigPlus::const_get(name)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module ConfigPlus
|
4
|
+
class DefaultLoaderLogic
|
5
|
+
def initialize(config)
|
6
|
+
@config = config
|
7
|
+
end
|
8
|
+
|
9
|
+
def extension
|
10
|
+
@config.extension || [:yml, :yaml]
|
11
|
+
end
|
12
|
+
|
13
|
+
def load_from(path)
|
14
|
+
return load_file(path) if File.file?(path)
|
15
|
+
load_dir(path)
|
16
|
+
end
|
17
|
+
|
18
|
+
def load_file(filepath)
|
19
|
+
content = open(filepath).read
|
20
|
+
YAML.load(content).to_hash
|
21
|
+
end
|
22
|
+
|
23
|
+
def load_dir(dirpath)
|
24
|
+
ext = Array(extension).join(',')
|
25
|
+
path = File.join(dirpath, '**', "*.{#{ext}}")
|
26
|
+
Dir.glob(path).sort.inject({}) {|h, filepath|
|
27
|
+
Merger.merge(h, load_file(filepath))
|
28
|
+
}
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module ConfigPlus
|
2
|
+
module Helper
|
3
|
+
class << self
|
4
|
+
def config_for(object, config)
|
5
|
+
configs = matched_configs(object, config)
|
6
|
+
return configs.first if configs.size <= 1
|
7
|
+
|
8
|
+
if configs.all? {|c| c.is_a? Hash }
|
9
|
+
configs.inject(::ConfigPlus::Node.new) {|h, conf|
|
10
|
+
::ConfigPlus::Merger.merge(h, conf)
|
11
|
+
}
|
12
|
+
else
|
13
|
+
configs.inject([]) {|a, conf| a << conf }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def underscore(name)
|
18
|
+
name.gsub(/::/, '.')
|
19
|
+
.gsub(/((\A|\b)([A-Z]+))|([A-Z]+)/) do
|
20
|
+
next $3.downcase if $3
|
21
|
+
"_#{$4.downcase}"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def matched_configs(object, node)
|
28
|
+
return [] unless node
|
29
|
+
mod = object.is_a?(Module) ? object : object.class
|
30
|
+
path = underscore(mod.name)
|
31
|
+
|
32
|
+
[node[mod.name],
|
33
|
+
node[path],
|
34
|
+
node.get(path),
|
35
|
+
].uniq.compact
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module ConfigPlus
|
2
|
+
class Loader
|
3
|
+
def initialize(config)
|
4
|
+
@config = config
|
5
|
+
end
|
6
|
+
|
7
|
+
def load
|
8
|
+
paths = source_paths
|
9
|
+
raise "No specified `source'" if paths.empty?
|
10
|
+
|
11
|
+
paths.each.inject({}) do |h, path|
|
12
|
+
hsh = loader_logic.load_from(path)
|
13
|
+
hsh = hsh[@config.namespace.to_s] if @config.namespace
|
14
|
+
Merger.merge(h, hsh)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
protected
|
19
|
+
|
20
|
+
def loader_logic
|
21
|
+
@loader_logic ||= @config.loader_logic.new(@config)
|
22
|
+
end
|
23
|
+
|
24
|
+
def source_paths
|
25
|
+
Array(@config.source).map {|s|
|
26
|
+
source_path(s)
|
27
|
+
}.reverse.uniq.compact.reverse
|
28
|
+
end
|
29
|
+
|
30
|
+
def source_path(filepath)
|
31
|
+
return filepath unless @config.root_dir
|
32
|
+
return @config.root_dir unless filepath
|
33
|
+
return filepath if filepath.start_with?('/')
|
34
|
+
File.join(@config.root_dir, filepath)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module ConfigPlus
|
2
|
+
module Merger
|
3
|
+
MERGER = ->(key, h1, h2) do
|
4
|
+
if h1.is_a?(Hash) and h2.is_a?(Hash)
|
5
|
+
h1.merge(h2, &MERGER)
|
6
|
+
else
|
7
|
+
h2
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.merge(collection1, collection2)
|
12
|
+
return collection2 unless collection1
|
13
|
+
return collection1 unless collection2
|
14
|
+
|
15
|
+
if collection1.is_a?(Array) and
|
16
|
+
collection2.is_a?(Array)
|
17
|
+
collection1.concat(collection2)
|
18
|
+
else
|
19
|
+
collection1.merge(collection2, &MERGER)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module ConfigPlus
|
2
|
+
class Node < Hash
|
3
|
+
def initialize(hash = nil)
|
4
|
+
node = super()
|
5
|
+
node.merge!(hash) if hash
|
6
|
+
end
|
7
|
+
|
8
|
+
def [](key)
|
9
|
+
value = self.fetch(key.to_s, nil)
|
10
|
+
value = self.fetch(key.to_i, nil) if
|
11
|
+
value.nil? and key.to_s =~ /\A\d+\z/
|
12
|
+
return value unless value.is_a?(Hash)
|
13
|
+
return value if value.is_a?(self.class)
|
14
|
+
|
15
|
+
self.store(key.to_s, self.class.new(value))
|
16
|
+
end
|
17
|
+
|
18
|
+
def get(path)
|
19
|
+
key, rest = path.split('.', 2)
|
20
|
+
return self[key] unless rest
|
21
|
+
return nil unless self[key]
|
22
|
+
self[key].get(rest)
|
23
|
+
end
|
24
|
+
|
25
|
+
def merge!(hash)
|
26
|
+
result = super
|
27
|
+
hash.keys.each {|k| define_accessor(k) }
|
28
|
+
result
|
29
|
+
end
|
30
|
+
|
31
|
+
def merge(hash)
|
32
|
+
result = super
|
33
|
+
result.instance_eval {
|
34
|
+
hash.keys.each {|k| define_accessor(k) }
|
35
|
+
}
|
36
|
+
result
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def define_accessor(method_name)
|
42
|
+
return unless method_name.is_a?(String) or
|
43
|
+
method_name.is_a?(Symbol)
|
44
|
+
return if respond_to?(method_name) or
|
45
|
+
private_methods.include?(method_name.to_sym)
|
46
|
+
singleton_class.class_eval do
|
47
|
+
define_method method_name, -> { self[method_name] }
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
metadata
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: config_plus
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- m4oda
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-04-03 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rspec
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '3.4'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '3.4'
|
27
|
+
description: ConfigPlus is an easy-to-use configuration module that uses YAML files
|
28
|
+
and has powerful features such as auto mapping.
|
29
|
+
email: e5ww2sze@gmail.com
|
30
|
+
executables: []
|
31
|
+
extensions: []
|
32
|
+
extra_rdoc_files: []
|
33
|
+
files:
|
34
|
+
- README.ja.md
|
35
|
+
- README.md
|
36
|
+
- lib/config_plus.rb
|
37
|
+
- lib/config_plus/base.rb
|
38
|
+
- lib/config_plus/config.rb
|
39
|
+
- lib/config_plus/default_loader_logic.rb
|
40
|
+
- lib/config_plus/helper.rb
|
41
|
+
- lib/config_plus/loader.rb
|
42
|
+
- lib/config_plus/merger.rb
|
43
|
+
- lib/config_plus/node.rb
|
44
|
+
- lib/config_plus/version.rb
|
45
|
+
homepage: https://github.com/m4oda/config_plus
|
46
|
+
licenses:
|
47
|
+
- MIT
|
48
|
+
metadata: {}
|
49
|
+
post_install_message:
|
50
|
+
rdoc_options: []
|
51
|
+
require_paths:
|
52
|
+
- lib
|
53
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: '0'
|
58
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0'
|
63
|
+
requirements: []
|
64
|
+
rubyforge_project:
|
65
|
+
rubygems_version: 2.4.5
|
66
|
+
signing_key:
|
67
|
+
specification_version: 4
|
68
|
+
summary: An easy-to-use, powerful configuration module using YAML files
|
69
|
+
test_files: []
|