config_leaf 0.0.1
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.
- data/.gitignore +18 -0
- data/Gemfile +3 -0
- data/LICENSE +22 -0
- data/README.md +86 -0
- data/Rakefile +19 -0
- data/config_leaf.gemspec +27 -0
- data/lib/config_leaf/version.rb +3 -0
- data/lib/config_leaf/wrapper.rb +47 -0
- data/lib/config_leaf.rb +82 -0
- data/spec/config_leaf/config_leaf_spec.rb +45 -0
- data/spec/config_leaf/wrapper_spec.rb +110 -0
- data/spec/teststrap.rb +8 -0
- metadata +153 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Bil Bas (Spooner)
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
ConfigLeaf
|
2
|
+
==========
|
3
|
+
|
4
|
+
ConfigLeaf allows an object to be configured using a terse syntax
|
5
|
+
like Object#instance_eval, while not exposing the internals
|
6
|
+
(protected/private methods and ivars) of the object!
|
7
|
+
|
8
|
+
If the user doesn't like to use this ConfigLeaf wrapping, then they
|
9
|
+
can just use normal #tap syntax by requesting a block parameter.
|
10
|
+
|
11
|
+
Installation
|
12
|
+
------------
|
13
|
+
|
14
|
+
Add this line to your application's Gemfile:
|
15
|
+
|
16
|
+
gem 'config_leaf'
|
17
|
+
|
18
|
+
And then execute:
|
19
|
+
|
20
|
+
$ bundle
|
21
|
+
|
22
|
+
Or install it yourself as:
|
23
|
+
|
24
|
+
$ gem install config_leaf
|
25
|
+
|
26
|
+
Usage
|
27
|
+
-----
|
28
|
+
|
29
|
+
ConfigLeaf can be used directly by the end-user after an object has been created,
|
30
|
+
but it more likely used by those wanting to allow block setting of config after
|
31
|
+
their object has been instantiated:
|
32
|
+
|
33
|
+
require 'config_leaf'
|
34
|
+
|
35
|
+
class Cheese
|
36
|
+
attr_accessor :value, :list
|
37
|
+
|
38
|
+
def initialize(&block)
|
39
|
+
# Set defaults.
|
40
|
+
@value = 0
|
41
|
+
@list = []
|
42
|
+
|
43
|
+
# Allow the user access via ConfigLeaf syntax.
|
44
|
+
ConfigLeaf.wrap object, &block if block_given?
|
45
|
+
end
|
46
|
+
|
47
|
+
def reverse!
|
48
|
+
@list.reverse!
|
49
|
+
end
|
50
|
+
|
51
|
+
protected
|
52
|
+
def explode!
|
53
|
+
DeathStar.instance.boom!
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# User uses the ConfigLeaf block.
|
58
|
+
object = Cheese.new do
|
59
|
+
list [1, 2, 3] # Calls object.list = [1, 2, 3]
|
60
|
+
list << 4 # Calls object.list << 4
|
61
|
+
value 5 # Calls object.value = 5
|
62
|
+
value list.size # Calls object.value = object.list.size
|
63
|
+
reverse! # Calls object.reverse!
|
64
|
+
|
65
|
+
# These would be possible if using instance_eval, but not here.
|
66
|
+
#explode! # Not allowed because it is protected (raises an exception).
|
67
|
+
#@value = 5 # Would set @value on the wrapper, not in the wrapped object, so has no effect.
|
68
|
+
end
|
69
|
+
|
70
|
+
# User chooses to not use ConfigLeaf block syntax by requesting a block parameter.
|
71
|
+
object = Cheese.new do |c|
|
72
|
+
c.list = [1, 2, 3]
|
73
|
+
c.list << 4
|
74
|
+
c.value = 5
|
75
|
+
c.value = c.list.size
|
76
|
+
c.reverse!
|
77
|
+
end
|
78
|
+
|
79
|
+
Contributing
|
80
|
+
------------
|
81
|
+
|
82
|
+
1. Fork it
|
83
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
84
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
85
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
86
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
require 'bundler/setup'
|
3
|
+
|
4
|
+
require 'bundler/gem_tasks'
|
5
|
+
require 'rake/clean'
|
6
|
+
require 'rake/testtask'
|
7
|
+
require 'rspec/core/rake_task'
|
8
|
+
|
9
|
+
CLOBBER.include('doc/**/*')
|
10
|
+
|
11
|
+
desc 'Generate Yard docs.'
|
12
|
+
task :yard do
|
13
|
+
system 'yard doc lib'
|
14
|
+
end
|
15
|
+
|
16
|
+
RSpec::Core::RakeTask.new do
|
17
|
+
end
|
18
|
+
|
19
|
+
task :default => :spec
|
data/config_leaf.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/config_leaf/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Bil Bas (Spooner)"]
|
6
|
+
gem.email = ["bil.bagpuss@gmail.com"]
|
7
|
+
gem.description = <<END
|
8
|
+
ConfigLeaf allows an object to be configured using a terse syntax
|
9
|
+
like Object#instance_eval, while not exposing the internals
|
10
|
+
(protected/private methods and ivars) of the object!
|
11
|
+
END
|
12
|
+
gem.summary = %q{Terse configuration syntax for objects}
|
13
|
+
gem.homepage = "https://github.com/spooner/config_leaf"
|
14
|
+
|
15
|
+
gem.files = `git ls-files`.split($\)
|
16
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
|
+
gem.name = "config_leaf"
|
19
|
+
gem.require_paths = ["lib"]
|
20
|
+
gem.version = ConfigLeaf::VERSION
|
21
|
+
|
22
|
+
gem.add_development_dependency "rspec", "~> 2.11.0"
|
23
|
+
gem.add_development_dependency "rr", "~> 1.0.4"
|
24
|
+
gem.add_development_dependency "yard", "~> 0.8.3"
|
25
|
+
gem.add_development_dependency "redcarpet", "~> 2.1.1"
|
26
|
+
gem.add_development_dependency "rake"
|
27
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module ConfigLeaf
|
2
|
+
|
3
|
+
class Wrapper
|
4
|
+
# @return [Object] Object that the Wrapper object is redirecting to.
|
5
|
+
attr_reader :_owner
|
6
|
+
|
7
|
+
class << self
|
8
|
+
# Synonym for .new.
|
9
|
+
alias_method :wrap, :new
|
10
|
+
end
|
11
|
+
|
12
|
+
# If passed a block, the DSLWrapper will #instance_eval it automatically.
|
13
|
+
#
|
14
|
+
# @param owner [Object] Object to redirect the public methods of.
|
15
|
+
def initialize(owner, &block)
|
16
|
+
@_owner = owner
|
17
|
+
|
18
|
+
metaclass = class << self; self; end
|
19
|
+
|
20
|
+
(@_owner.public_methods - Object.public_instance_methods).each do |target_method|
|
21
|
+
redirection_method = target_method.to_s.chomp('=').to_sym
|
22
|
+
|
23
|
+
metaclass.class_eval do
|
24
|
+
define_method redirection_method do |*args, &inner_block|
|
25
|
+
if @_owner.respond_to? "#{redirection_method}=" and (args.any? or not @_owner.respond_to? redirection_method)
|
26
|
+
# Has a setter and we are passing argument(s) or if we haven't got a corresponding getter.
|
27
|
+
@_owner.send "#{redirection_method}=", *args, &inner_block
|
28
|
+
elsif @_owner.respond_to? redirection_method
|
29
|
+
# We have a getter or general method
|
30
|
+
@_owner.send redirection_method, *args, &inner_block
|
31
|
+
else
|
32
|
+
# Should never reach here, but let's be paranoid.
|
33
|
+
raise NoMethodError, "#{@_owner} does not have a public method, ##{redirection_method}"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
instance_eval &block if block_given?
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
def method_missing(meth, *args, &block)
|
44
|
+
raise NoMethodError, "#{_owner} does not have either public method, ##{meth} or ##{meth}="
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
data/lib/config_leaf.rb
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'config_leaf/version'
|
2
|
+
require 'config_leaf/wrapper'
|
3
|
+
|
4
|
+
module ConfigLeaf
|
5
|
+
class << self
|
6
|
+
# Wraps an object and redirects public methods to it, to allow for a terse, block-based API.
|
7
|
+
#
|
8
|
+
# * Safer alternative to running Object#instance_eval directly, since protected/private methods and instance variables are not exposed.
|
9
|
+
# * Less wordy than a system which operates like Object#tap (`object.tap {|o| o.fish = 5; o.run }`)
|
10
|
+
#
|
11
|
+
# A method call, #meth called on the wrapper will try to call #meth or #meth= on the owner, as appropriate.
|
12
|
+
#
|
13
|
+
# @example Using ConfigLeaf to configure an object externally.
|
14
|
+
# # To create a DSL block for a given object.
|
15
|
+
# class Cheese
|
16
|
+
# attr_accessor :value, :list
|
17
|
+
#
|
18
|
+
# def initialize
|
19
|
+
# @value = 0
|
20
|
+
# @list = []
|
21
|
+
# end
|
22
|
+
#
|
23
|
+
# def invert
|
24
|
+
# @list.reverse!
|
25
|
+
# end
|
26
|
+
# end
|
27
|
+
#
|
28
|
+
# object = Cheese.new
|
29
|
+
# ConfigLeaf.wrap object do
|
30
|
+
# list [1, 2, 3] # Calls object.list = [1, 2, 3]
|
31
|
+
# list << 4 # Calls object.list << 4
|
32
|
+
# value 5 # Calls object.value = 5
|
33
|
+
# value list.size # Calls object.value = object.list.size
|
34
|
+
# invert # Calls object.invert
|
35
|
+
# end
|
36
|
+
#
|
37
|
+
# @example Allowing the user to configure the object externally.
|
38
|
+
# # To create a DSL block for a given object.
|
39
|
+
# class Cheese
|
40
|
+
# attr_accessor :value, :list
|
41
|
+
#
|
42
|
+
# def initialize(&block)
|
43
|
+
# @value = 0
|
44
|
+
# @list = []
|
45
|
+
#
|
46
|
+
# ConfigLeaf.wrap object, &block if block_given?
|
47
|
+
# end
|
48
|
+
#
|
49
|
+
# def invert
|
50
|
+
# @list.reverse!
|
51
|
+
# end
|
52
|
+
# end
|
53
|
+
#
|
54
|
+
# # User chooses to use the ConfigLeaf block syntax.
|
55
|
+
# object = Cheese.new do
|
56
|
+
# list [1, 2, 3] # Calls object.list = [1, 2, 3]
|
57
|
+
# list << 4 # Calls object.list << 4
|
58
|
+
# value 5 # Calls object.value = 5
|
59
|
+
# value list.size # Calls object.value = object.list.size
|
60
|
+
# invert # Calls object.invert
|
61
|
+
# end
|
62
|
+
#
|
63
|
+
# # User chooses to not use ConfigLeaf block syntax by requesting a block parameter.
|
64
|
+
# object = Cheese.new do |c|
|
65
|
+
# c.list = [1, 2, 3]
|
66
|
+
# c.list << 4
|
67
|
+
# c.value = 5
|
68
|
+
# c.value = c.list.size
|
69
|
+
# c.invert
|
70
|
+
# end
|
71
|
+
#
|
72
|
+
def wrap(object, &block)
|
73
|
+
raise ArgumentError, "block is required" unless block_given?
|
74
|
+
|
75
|
+
if block.arity == 0 # e.g. { }
|
76
|
+
Wrapper.wrap object, &block
|
77
|
+
else # e.g. {|me| }
|
78
|
+
block.call object
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require File.expand_path("../../teststrap", __FILE__)
|
2
|
+
|
3
|
+
describe ConfigLeaf do
|
4
|
+
describe ".wrap" do
|
5
|
+
it "should fail without a block" do
|
6
|
+
lambda { ConfigLeaf.wrap Object.new }.should raise_error ArgumentError, "block is required"
|
7
|
+
end
|
8
|
+
|
9
|
+
context "without block arguments" do
|
10
|
+
it "should alter the context to that of the wrapper within the block" do
|
11
|
+
passed = nil
|
12
|
+
ConfigLeaf.wrap Object.new do
|
13
|
+
passed = self
|
14
|
+
end
|
15
|
+
passed.should be_kind_of ConfigLeaf::Wrapper
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
context "with block arguments" do
|
20
|
+
it "should pass object into the block" do
|
21
|
+
object = Object.new
|
22
|
+
passed = nil
|
23
|
+
|
24
|
+
ConfigLeaf.wrap object do |x|
|
25
|
+
passed = x
|
26
|
+
end
|
27
|
+
|
28
|
+
passed.should eq object
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should not alter the context in the block" do
|
32
|
+
object = Object.new
|
33
|
+
block_self = nil
|
34
|
+
original_self = self
|
35
|
+
|
36
|
+
ConfigLeaf.wrap object do |x|
|
37
|
+
block_self = self
|
38
|
+
end
|
39
|
+
|
40
|
+
# Use id or the two rspec contexts will barf.
|
41
|
+
original_self.__id__.should eq block_self.__id__
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
require File.expand_path("../../teststrap", __FILE__)
|
2
|
+
|
3
|
+
class Owner
|
4
|
+
def frog; end
|
5
|
+
def fish; end
|
6
|
+
def fish=(fish); end
|
7
|
+
def knees=(knees); end
|
8
|
+
def add_cheese(a, b); end
|
9
|
+
def add_peas(a, &block); end
|
10
|
+
|
11
|
+
protected
|
12
|
+
def wibble; end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe ConfigLeaf::Wrapper do
|
16
|
+
let(:owner) { Owner.new }
|
17
|
+
let(:subject) { described_class.wrap owner }
|
18
|
+
|
19
|
+
let :expected_methods do
|
20
|
+
methods = [:frog, :fish, :add_cheese, :_owner, :add_peas, :knees]
|
21
|
+
methods.map! &:to_s if RUBY_VERSION =~ /^1\.8\./
|
22
|
+
methods
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "#public_methods" do
|
26
|
+
it "should be the same as the owner's + #_owner" do
|
27
|
+
subject.public_methods(false).sort.should eq expected_methods.sort
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "#_owner" do
|
32
|
+
it "should be set to the owner of the wrapper" do
|
33
|
+
subject._owner.should eq owner
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context "dynamic method redirection" do
|
38
|
+
it "a method that doesn't exist on the wrapped object should fail" do
|
39
|
+
lambda { subject.wobble }.should raise_error NoMethodError, /<Owner:0x\w+> does not have either public method, #wobble or #wobble=/
|
40
|
+
end
|
41
|
+
|
42
|
+
it "a protected method on the wrapped object should not be accessible" do
|
43
|
+
lambda { subject.wibble }.should raise_error NoMethodError, /<Owner:0x\w+> does not have either public method, #wibble or #wibble=/
|
44
|
+
end
|
45
|
+
|
46
|
+
it "redirect to a setter, that has no corresponding getter, even if no arguments are passed" do
|
47
|
+
lambda { subject.knees }.should raise_error ArgumentError
|
48
|
+
end
|
49
|
+
|
50
|
+
it "redirect to a getter, that has no corresponding setter, even if arguments are passed" do
|
51
|
+
lambda { subject.frog 25 }.should raise_error ArgumentError
|
52
|
+
end
|
53
|
+
|
54
|
+
it "redirect a getter (that has no corresponding setter)" do
|
55
|
+
mock(owner, :frog).returns 5
|
56
|
+
subject.frog.should eq 5
|
57
|
+
end
|
58
|
+
|
59
|
+
it "redirect a setter (that has no corresponding getter)" do
|
60
|
+
mock(owner, :knees=).with(1).returns(5)
|
61
|
+
subject.knees(1).should eq 5
|
62
|
+
end
|
63
|
+
|
64
|
+
it "redirect a getter (that has a corresponding setter)" do
|
65
|
+
mock(owner, :fish).returns(5)
|
66
|
+
subject.fish.should eq 5
|
67
|
+
end
|
68
|
+
|
69
|
+
it "redirect a setter (that has a corresponding getter)" do
|
70
|
+
mock(owner, :fish=).with(5).returns(5)
|
71
|
+
subject.fish(5).should eq 5
|
72
|
+
end
|
73
|
+
|
74
|
+
it "redirect a setter (that has a corresponding getter)" do
|
75
|
+
mock(owner).add_cheese(1, 2).returns(99)
|
76
|
+
subject.add_cheese(1, 2).should eq 99
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should redirect a block as well as pass arguments" do
|
80
|
+
mock(owner).add_peas(1).yields(:knees)
|
81
|
+
|
82
|
+
yielded = nil
|
83
|
+
subject.add_peas(1) do |arg|
|
84
|
+
yielded = arg
|
85
|
+
end
|
86
|
+
|
87
|
+
yielded.should eq :knees
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
describe "" do
|
92
|
+
it "should instance_eval when given a block on the constructor (.new)" do
|
93
|
+
mock(owner).frog(5)
|
94
|
+
|
95
|
+
ConfigLeaf::Wrapper.new owner do
|
96
|
+
frog 5
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
describe ".wrap" do
|
102
|
+
it "should be an alias for .new" do
|
103
|
+
described_class.wrap(owner).should be_kind_of described_class
|
104
|
+
end
|
105
|
+
|
106
|
+
it "should be an alias for .new given a block" do
|
107
|
+
described_class.wrap(owner) {}.should be_kind_of described_class
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
data/spec/teststrap.rb
ADDED
metadata
ADDED
@@ -0,0 +1,153 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: config_leaf
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Bil Bas (Spooner)
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-10-19 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rspec
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 2.11.0
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 2.11.0
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rr
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 1.0.4
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 1.0.4
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: yard
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ~>
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 0.8.3
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.8.3
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: redcarpet
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ~>
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: 2.1.1
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ~>
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: 2.1.1
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: rake
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
description: ! 'ConfigLeaf allows an object to be configured using a terse syntax
|
95
|
+
|
96
|
+
like Object#instance_eval, while not exposing the internals
|
97
|
+
|
98
|
+
(protected/private methods and ivars) of the object!
|
99
|
+
|
100
|
+
'
|
101
|
+
email:
|
102
|
+
- bil.bagpuss@gmail.com
|
103
|
+
executables: []
|
104
|
+
extensions: []
|
105
|
+
extra_rdoc_files: []
|
106
|
+
files:
|
107
|
+
- .gitignore
|
108
|
+
- Gemfile
|
109
|
+
- LICENSE
|
110
|
+
- README.md
|
111
|
+
- Rakefile
|
112
|
+
- config_leaf.gemspec
|
113
|
+
- lib/config_leaf.rb
|
114
|
+
- lib/config_leaf/version.rb
|
115
|
+
- lib/config_leaf/wrapper.rb
|
116
|
+
- spec/config_leaf/config_leaf_spec.rb
|
117
|
+
- spec/config_leaf/wrapper_spec.rb
|
118
|
+
- spec/teststrap.rb
|
119
|
+
homepage: https://github.com/spooner/config_leaf
|
120
|
+
licenses: []
|
121
|
+
post_install_message:
|
122
|
+
rdoc_options: []
|
123
|
+
require_paths:
|
124
|
+
- lib
|
125
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
126
|
+
none: false
|
127
|
+
requirements:
|
128
|
+
- - ! '>='
|
129
|
+
- !ruby/object:Gem::Version
|
130
|
+
version: '0'
|
131
|
+
segments:
|
132
|
+
- 0
|
133
|
+
hash: 196843955
|
134
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
135
|
+
none: false
|
136
|
+
requirements:
|
137
|
+
- - ! '>='
|
138
|
+
- !ruby/object:Gem::Version
|
139
|
+
version: '0'
|
140
|
+
segments:
|
141
|
+
- 0
|
142
|
+
hash: 196843955
|
143
|
+
requirements: []
|
144
|
+
rubyforge_project:
|
145
|
+
rubygems_version: 1.8.23
|
146
|
+
signing_key:
|
147
|
+
specification_version: 3
|
148
|
+
summary: Terse configuration syntax for objects
|
149
|
+
test_files:
|
150
|
+
- spec/config_leaf/config_leaf_spec.rb
|
151
|
+
- spec/config_leaf/wrapper_spec.rb
|
152
|
+
- spec/teststrap.rb
|
153
|
+
has_rdoc:
|