indifferent_eval 0.1.1 → 0.2.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.
- data/.ci +7 -0
- data/.gitignore +5 -0
- data/Gemfile +3 -0
- data/README.markdown +93 -0
- data/Rakefile +15 -0
- data/indifferent_eval.gemspec +24 -0
- data/lib/indifferent_eval/module.rb +4 -11
- data/lib/indifferent_eval/version.rb +8 -0
- data/lib/indifferent_eval.rb +1 -1
- data/sample.rb +32 -0
- data/spec/indifferent_eval_spec.rb +86 -0
- metadata +67 -43
data/.ci
ADDED
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.markdown
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
Indifferent Eval
|
2
|
+
================
|
3
|
+
|
4
|
+
When you're making a Ruby DSL, you often have to decide between:
|
5
|
+
|
6
|
+
```ruby
|
7
|
+
# Use a block variable to access the MyConfig instance.
|
8
|
+
# This gives you the benefit of having access to the outer "self" inside of the block.
|
9
|
+
MyApp.config do |config|
|
10
|
+
config.verbosity true
|
11
|
+
config.foo :bar
|
12
|
+
end
|
13
|
+
```
|
14
|
+
|
15
|
+
and:
|
16
|
+
|
17
|
+
```ruby
|
18
|
+
# Don't pass a block variable. All method calls are sent to the MyConfig instance.
|
19
|
+
# This has the benefit of looking really clean (but no access to "self" inside the block).
|
20
|
+
MyApp.config do
|
21
|
+
verbosity true
|
22
|
+
foo :bar
|
23
|
+
end
|
24
|
+
```
|
25
|
+
|
26
|
+
There are a number of pros and cons to each of these approaches.
|
27
|
+
|
28
|
+
Wouldn't it be nice if you could support both? That's what `#indifferent_eval` is for!
|
29
|
+
|
30
|
+
Install
|
31
|
+
-------
|
32
|
+
|
33
|
+
```ruby
|
34
|
+
# In your Gemfile
|
35
|
+
gem "indifferent_eval"
|
36
|
+
```
|
37
|
+
|
38
|
+
The Code
|
39
|
+
--------
|
40
|
+
|
41
|
+
The code is tiny. This gem exists only for convenience.
|
42
|
+
|
43
|
+
```ruby
|
44
|
+
module IndifferentEval
|
45
|
+
def indifferent_eval(object_to_eval_on = self, &block)
|
46
|
+
if block.arity == 0 || block.arity == -1
|
47
|
+
object_to_eval_on.instance_eval &block
|
48
|
+
else
|
49
|
+
block.call object_to_eval_on
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
```
|
54
|
+
|
55
|
+
([Annotated source code](https://github.com/remi/indifferent_eval/blob/master/lib/indifferent_eval/module.rb))
|
56
|
+
|
57
|
+
Usage
|
58
|
+
-----
|
59
|
+
|
60
|
+
```ruby
|
61
|
+
require "indifferent_eval"
|
62
|
+
|
63
|
+
class MyLibrary
|
64
|
+
def self.config(&block)
|
65
|
+
@config = MyConfig.new.indifferent_eval(&block)
|
66
|
+
end
|
67
|
+
|
68
|
+
class MyConfig
|
69
|
+
attr_writer :some_setting
|
70
|
+
|
71
|
+
def some_setting(value = nil)
|
72
|
+
@some_setting = value if value
|
73
|
+
@some_setting
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# Use a block variable to access the MyConfig instance.
|
79
|
+
# This gives you the benefit of having access to the outer "self" inside of the block.
|
80
|
+
MyLibrary.config do |config|
|
81
|
+
config.some_setting = "Called a method with a block variable"
|
82
|
+
end
|
83
|
+
|
84
|
+
# Don't pass a block variable. All method calls are sent to the MyConfig instance.
|
85
|
+
# This has the benefit of looking really clean (but no access to "self" inside the block).
|
86
|
+
MyLibrary.config do
|
87
|
+
some_setting "Called a method without a block variable"
|
88
|
+
end
|
89
|
+
```
|
90
|
+
|
91
|
+
## License
|
92
|
+
|
93
|
+
indifferent_eval is released under the MIT license.
|
data/Rakefile
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require "rspec/core/rake_task"
|
2
|
+
|
3
|
+
desc 'Default: run specs'
|
4
|
+
task :default => :spec
|
5
|
+
|
6
|
+
desc 'Run tests'
|
7
|
+
task :test => :spec
|
8
|
+
|
9
|
+
desc 'Run sample.rb'
|
10
|
+
task :sample do
|
11
|
+
exec "bundle exec ruby sample.rb"
|
12
|
+
end
|
13
|
+
|
14
|
+
desc "Run specs"
|
15
|
+
RSpec::Core::RakeTask.new
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path("../lib/indifferent_eval/version", __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.name = "indifferent_eval"
|
6
|
+
gem.author = "remi"
|
7
|
+
gem.email = "remi@remitaylor.com"
|
8
|
+
gem.homepage = "http://github.com/remi/indifferent_eval"
|
9
|
+
gem.summary = "Can't decide between instance_eval and block.call? Why not support both!?"
|
10
|
+
|
11
|
+
gem.description = <<-desc.gsub(/^\s+/, '')
|
12
|
+
Can't decide between instance_eval and block.call? Why not support both!?
|
13
|
+
desc
|
14
|
+
|
15
|
+
files = `git ls-files`.split("\n")
|
16
|
+
gem.files = files
|
17
|
+
gem.executables = files.grep(%r{^bin/.*}).map {|f| File.basename(f) }
|
18
|
+
gem.test_files = files.grep(%r{^spec/.*})
|
19
|
+
gem.require_paths = ["lib"]
|
20
|
+
gem.version = IndifferentEval::VERSION
|
21
|
+
|
22
|
+
gem.add_development_dependency "rake"
|
23
|
+
gem.add_development_dependency "rspec"
|
24
|
+
end
|
@@ -1,16 +1,9 @@
|
|
1
1
|
module IndifferentEval
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
if block.arity == -1
|
6
|
-
# no block variable, use instance_eval
|
7
|
-
object_to_eval_on.instance_eval &block
|
8
|
-
|
2
|
+
def indifferent_eval(object_to_eval_on = self, &block)
|
3
|
+
if block.arity == 0 || block.arity == -1 # Blocks with no arguments return -1 in Ruby 1.8 but 0 in Ruby 1.9.
|
4
|
+
object_to_eval_on.instance_eval &block # No block variable so use instance_eval on the object.
|
9
5
|
else
|
10
|
-
#
|
11
|
-
block.call object_to_eval_on
|
6
|
+
block.call object_to_eval_on # Block variable passed so #call the block with the object as the variable.
|
12
7
|
end
|
13
|
-
|
14
8
|
end
|
15
|
-
|
16
9
|
end
|
data/lib/indifferent_eval.rb
CHANGED
data/sample.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# Run via: bundle exec rake sample
|
2
|
+
require "indifferent_eval"
|
3
|
+
|
4
|
+
class MyLibrary
|
5
|
+
def self.config(&block)
|
6
|
+
@config = MyConfig.new.indifferent_eval(&block) if block
|
7
|
+
@config
|
8
|
+
end
|
9
|
+
|
10
|
+
class MyConfig
|
11
|
+
attr_writer :some_setting
|
12
|
+
|
13
|
+
def some_setting(value = nil)
|
14
|
+
@some_setting = value if value
|
15
|
+
@some_setting
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
puts MyLibrary.config.inspect
|
21
|
+
|
22
|
+
MyLibrary.config do |config|
|
23
|
+
config.some_setting = "Called a method with a block variable"
|
24
|
+
end
|
25
|
+
|
26
|
+
puts MyLibrary.config.inspect
|
27
|
+
|
28
|
+
MyLibrary.config do
|
29
|
+
some_setting "Called a method without a block variable"
|
30
|
+
end
|
31
|
+
|
32
|
+
puts MyLibrary.config.inspect
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'indifferent_eval'
|
2
|
+
require 'rspec'
|
3
|
+
|
4
|
+
# sample configuration object
|
5
|
+
class SampleConfig
|
6
|
+
attr_accessor :value
|
7
|
+
def set_value(val) self.value = val end
|
8
|
+
end
|
9
|
+
|
10
|
+
# sample App class that has configuration
|
11
|
+
class App
|
12
|
+
class << self; attr_accessor :config; end
|
13
|
+
@config = SampleConfig.new
|
14
|
+
|
15
|
+
def self.configure &block
|
16
|
+
indifferent_eval self.config, &block
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# this one has built-in config variables and we'll call
|
21
|
+
# indifferent_eval without an argument, so it should
|
22
|
+
# default to evaluating on self (the class)
|
23
|
+
class App2
|
24
|
+
class << self; attr_accessor :value; end
|
25
|
+
def self.set_value(val) self.value = val end
|
26
|
+
|
27
|
+
def self.configure &block
|
28
|
+
indifferent_eval &block
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe 'indifferent_eval' do
|
33
|
+
|
34
|
+
it 'should work with a block variable' do
|
35
|
+
App.config.value = nil
|
36
|
+
App2.value.should == nil
|
37
|
+
|
38
|
+
App.configure do |config|
|
39
|
+
config.set_value 'Hello'
|
40
|
+
end
|
41
|
+
|
42
|
+
App.config.value.should == 'Hello'
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'should work without a block variable' do
|
46
|
+
App.config.value = nil
|
47
|
+
App2.value.should == nil
|
48
|
+
|
49
|
+
App.configure do
|
50
|
+
set_value 'Hello'
|
51
|
+
end
|
52
|
+
|
53
|
+
App.config.value.should == 'Hello'
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'should have a good default (self) (should work with block variable)' do
|
57
|
+
App2.value = nil
|
58
|
+
App2.value.should == nil
|
59
|
+
|
60
|
+
App2.configure do |c|
|
61
|
+
c.set_value 'Hello'
|
62
|
+
end
|
63
|
+
App2.value.should == 'Hello'
|
64
|
+
|
65
|
+
App2.configure do |c|
|
66
|
+
c.value = 'There'
|
67
|
+
end
|
68
|
+
App2.value.should == 'There'
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'should have a good default (self) (should work without block variable)' do
|
72
|
+
App2.value = nil
|
73
|
+
App2.value.should == nil
|
74
|
+
|
75
|
+
App2.configure do
|
76
|
+
set_value 'Hello'
|
77
|
+
end
|
78
|
+
App2.value.should == 'Hello'
|
79
|
+
|
80
|
+
App2.configure do
|
81
|
+
self.value = 'There'
|
82
|
+
end
|
83
|
+
App2.value.should == 'There'
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
metadata
CHANGED
@@ -1,68 +1,92 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: indifferent_eval
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
prerelease:
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 1
|
9
|
-
- 1
|
10
|
-
version: 0.1.1
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.0
|
5
|
+
prerelease:
|
11
6
|
platform: ruby
|
12
|
-
authors:
|
7
|
+
authors:
|
13
8
|
- remi
|
14
9
|
autorequire:
|
15
10
|
bindir: bin
|
16
11
|
cert_chain: []
|
12
|
+
date: 2012-04-17 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rake
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '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: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rspec
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
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: '0'
|
46
|
+
description: ! 'Can''t decide between instance_eval and block.call? Why not support
|
47
|
+
both!?
|
17
48
|
|
18
|
-
|
19
|
-
default_executable:
|
20
|
-
dependencies: []
|
21
|
-
|
22
|
-
description: Can't decide between instance_eval and block.call? Why not support both!?
|
49
|
+
'
|
23
50
|
email: remi@remitaylor.com
|
24
51
|
executables: []
|
25
|
-
|
26
52
|
extensions: []
|
27
|
-
|
28
53
|
extra_rdoc_files: []
|
29
|
-
|
30
|
-
|
54
|
+
files:
|
55
|
+
- .ci
|
56
|
+
- .gitignore
|
57
|
+
- Gemfile
|
58
|
+
- README.markdown
|
59
|
+
- Rakefile
|
60
|
+
- indifferent_eval.gemspec
|
31
61
|
- lib/indifferent_eval.rb
|
32
62
|
- lib/indifferent_eval/module.rb
|
33
|
-
|
63
|
+
- lib/indifferent_eval/version.rb
|
64
|
+
- sample.rb
|
65
|
+
- spec/indifferent_eval_spec.rb
|
34
66
|
homepage: http://github.com/remi/indifferent_eval
|
35
67
|
licenses: []
|
36
|
-
|
37
68
|
post_install_message:
|
38
69
|
rdoc_options: []
|
39
|
-
|
40
|
-
require_paths:
|
70
|
+
require_paths:
|
41
71
|
- lib
|
42
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
72
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
43
73
|
none: false
|
44
|
-
requirements:
|
45
|
-
- -
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
|
48
|
-
|
49
|
-
- 0
|
50
|
-
version: "0"
|
51
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
52
79
|
none: false
|
53
|
-
requirements:
|
54
|
-
- -
|
55
|
-
- !ruby/object:Gem::Version
|
56
|
-
|
57
|
-
segments:
|
58
|
-
- 0
|
59
|
-
version: "0"
|
80
|
+
requirements:
|
81
|
+
- - ! '>='
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
60
84
|
requirements: []
|
61
|
-
|
62
85
|
rubyforge_project:
|
63
|
-
rubygems_version: 1.
|
86
|
+
rubygems_version: 1.8.21
|
64
87
|
signing_key:
|
65
88
|
specification_version: 3
|
66
89
|
summary: Can't decide between instance_eval and block.call? Why not support both!?
|
67
|
-
test_files:
|
68
|
-
|
90
|
+
test_files:
|
91
|
+
- spec/indifferent_eval_spec.rb
|
92
|
+
has_rdoc:
|