nil_conditional 0.0.1 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +3 -0
- data/README.md +51 -24
- data/lib/nil_conditional.rb +42 -12
- data/nil_conditional.gemspec +2 -3
- data/spec/local_variables_spec.rb +20 -0
- data/spec/nil_conditional_spec.rb +15 -0
- data/spec/nil_spec.rb +23 -0
- data/spec/object_spec.rb +14 -9
- metadata +10 -5
- data/lib/nil_conditional/version.rb +0 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 480a9c37b75244a79017defb5f87a09ec00bb4d2
|
4
|
+
data.tar.gz: c8ade086f96dccf7122da47898c418e923851579
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4cecbcded18c99be80b8a9ba7e69cc11bc6d5eeee237b67f5013f4f8e3c43027ca5d8e18220aad045d22decba661a971d027a8dd65fcbab69a2bbb48cd5709d6
|
7
|
+
data.tar.gz: 40bb5fd2b473e6fdcd3635cdff15aba19d7c2007b373efbe64e770995276192a860329d8e7ebebc9de0f0bf283ee66cd7af12df2baaeddfecaa6718719ab894b
|
data/.gitignore
CHANGED
data/.travis.yml
ADDED
data/README.md
CHANGED
@@ -2,49 +2,76 @@
|
|
2
2
|
|
3
3
|
Nil Conditional Operator in Ruby.
|
4
4
|
|
5
|
-
|
5
|
+
This is my approach to create Nil Conditional Operator in Ruby.
|
6
|
+
|
7
|
+
This is very simple, and it is merely an experiment, so use it on your own risk.
|
8
|
+
|
9
|
+
Nil Conditional Operator is inspired by Null Conditional Operator introduced in C# 6.0.
|
6
10
|
|
7
|
-
This gem introduces Nil Conditional Operator (`_?`) in Ruby, similar to Null Conditional Operator in C# 6.0.
|
8
11
|
|
9
12
|
## Installation
|
10
13
|
|
11
|
-
|
14
|
+
`nil_conditional` is gemified and available on RubyGems.
|
12
15
|
|
13
|
-
```ruby
|
14
|
-
gem 'nil_conditional'
|
15
|
-
```
|
16
16
|
|
17
|
-
|
17
|
+
## Usage
|
18
18
|
|
19
|
-
|
19
|
+
Use preceding double underscore (`__`) for methods (for ex. `__method`)
|
20
|
+
Use preceding double underscore and trailing block for local variables (for ex. `__var{}`)
|
20
21
|
|
21
|
-
|
22
|
+
```ruby
|
22
23
|
|
23
|
-
|
24
|
+
# logger is nil
|
25
|
+
logger.foo.bar.car.cow
|
26
|
+
NoMethodError: undefined method `foo` for #<NilClass>
|
24
27
|
|
25
|
-
|
28
|
+
# logger is nil or doesn't exist
|
29
|
+
__logger{}.foo.bar.car.cow
|
30
|
+
=> #<NilConditional>
|
26
31
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
=> nil
|
32
|
+
# object exists and all methods are valid
|
33
|
+
__object{}.foo.bar.car.cow
|
34
|
+
=> "moooo"
|
31
35
|
|
32
|
-
|
33
|
-
|
36
|
+
# logger exists but doesn't have warn method
|
37
|
+
logger.__warn('some warning')
|
38
|
+
=> #<NilConditional>
|
34
39
|
|
35
|
-
|
36
|
-
=>
|
40
|
+
__non_existent_local_variable{}
|
41
|
+
=> #<NilConditional>
|
37
42
|
|
38
|
-
|
39
|
-
=>
|
43
|
+
__non_existent_method
|
44
|
+
=> #<NilConditional>
|
40
45
|
|
41
|
-
|
42
|
-
|
46
|
+
Object.new.non_existent_method
|
47
|
+
NoMethodError: undefined method `non_existent_method` for #<Object>
|
43
48
|
|
44
|
-
Object.
|
49
|
+
Object.new.__non_existent_method
|
50
|
+
=> #<NilConditional>
|
51
|
+
|
52
|
+
Object.new.__non_existent_method.nil?
|
53
|
+
=> true
|
54
|
+
|
55
|
+
__new_object.foo.bar.car_?.cow_?
|
45
56
|
=> nil
|
46
57
|
```
|
47
58
|
|
59
|
+
`NilConditional` instanced return always new NilConditional object if method is missing.
|
60
|
+
These objects are also `eql` to `nil`.
|
61
|
+
|
62
|
+
|
63
|
+
## Changelog
|
64
|
+
|
65
|
+
* Changes from version with major 0
|
66
|
+
|
67
|
+
Previous version didn't support methods with special characters and there was no support for local variables
|
68
|
+
Previous version used trailing `_?` as NilConditional operator. Current version uses preceding double underscore character `__`.
|
69
|
+
|
70
|
+
|
71
|
+
## Discussion
|
72
|
+
|
73
|
+
Feel free to submit ideas via issues and discuss better solution to Nil Conditional Operator in Ruby
|
74
|
+
|
48
75
|
## License
|
49
76
|
|
50
77
|
This is free software, licensed under MIT License. See LICENSE.txt file.
|
data/lib/nil_conditional.rb
CHANGED
@@ -1,17 +1,47 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
1
|
+
# NilConditional Operator in Ruby
|
2
|
+
|
3
|
+
class Object
|
4
|
+
def method_missing(name, *params)
|
5
|
+
if name =~ /^__.+$/
|
6
|
+
original = name.to_s.sub(/^__/, '').to_sym
|
7
|
+
|
8
|
+
if block_given? && original =~ /^\w+$/
|
9
|
+
binding = Proc.new.binding
|
10
|
+
if binding.local_variable_defined?(original)
|
11
|
+
var = binding.local_variable_get(original)
|
12
|
+
return var unless var.nil?
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
if respond_to?(original)
|
17
|
+
return_value = block_given? ? send(original, *params, &Proc.new) :
|
18
|
+
send(original, *params)
|
19
|
+
return return_value unless return_value.nil?
|
13
20
|
end
|
21
|
+
|
22
|
+
NilConditional.new
|
23
|
+
else
|
24
|
+
super
|
14
25
|
end
|
15
26
|
end
|
27
|
+
end
|
16
28
|
|
29
|
+
class NilConditional
|
30
|
+
def method_missing(name, *params)
|
31
|
+
return self.class.new
|
32
|
+
end
|
33
|
+
|
34
|
+
def nil?
|
35
|
+
true
|
36
|
+
end
|
37
|
+
|
38
|
+
def ==(other)
|
39
|
+
return true if other == nil
|
40
|
+
super
|
41
|
+
end
|
42
|
+
|
43
|
+
def eql?(other)
|
44
|
+
return true if other.eql?(nil)
|
45
|
+
super
|
46
|
+
end
|
17
47
|
end
|
data/nil_conditional.gemspec
CHANGED
@@ -1,11 +1,10 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
lib = File.expand_path('../lib', __FILE__)
|
3
3
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require 'nil_conditional/version'
|
5
4
|
|
6
5
|
Gem::Specification.new do |spec|
|
7
6
|
spec.name = "nil_conditional"
|
8
|
-
spec.version =
|
7
|
+
spec.version = '1.0.0'
|
9
8
|
spec.authors = ["Grzegorz Bizon"]
|
10
9
|
spec.email = ["grzegorz.bizon@ntsn.pl"]
|
11
10
|
spec.summary = %q{Nil Conditional Operator in Ruby}
|
@@ -19,5 +18,5 @@ Gem::Specification.new do |spec|
|
|
19
18
|
|
20
19
|
spec.add_development_dependency "bundler", "~> 1.7"
|
21
20
|
spec.add_development_dependency "rake", "~> 10.0"
|
22
|
-
spec.add_development_dependency
|
21
|
+
spec.add_development_dependency "rspec", "~> 3.2.0"
|
23
22
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
describe 'local variables' do
|
2
|
+
context 'test variable' do
|
3
|
+
it 'should raise error when using non existent test variable' do
|
4
|
+
expect { test_variable }.to raise_error(NameError)
|
5
|
+
end
|
6
|
+
|
7
|
+
it 'should not raise error when using __test_variable{}' do
|
8
|
+
expect { __test_variable{} }.to_not raise_error
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'should return NilConditional instance when using non existent var with preceding __ and trailing block' do
|
12
|
+
expect(__test_variable{}).to be_a(NilConditional)
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'should support chained methods with nil conditional' do
|
16
|
+
expect { __test_variable{}.foo_?.bar_?.car_?.cow_? }.to_not raise_error
|
17
|
+
expect(__test_variable{}.foo_?.bar_?.car_?.cow_?).to be_a(NilConditional)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
describe NilConditional do
|
2
|
+
context 'nil value' do
|
3
|
+
it 'should be considered as nil' do
|
4
|
+
expect(NilConditional.new.nil?).to be(true)
|
5
|
+
expect(NilConditional.new).to eq(nil)
|
6
|
+
expect(NilConditional.new).to eql(nil)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
context 'missing method behavior' do
|
11
|
+
it 'return new NilConditional object when method is missing' do
|
12
|
+
expect(NilConditional.new.non_existent_method).to be_a(NilConditional)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/spec/nil_spec.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
describe 'nil object' do
|
2
|
+
context 'local variable' do
|
3
|
+
it 'should return nil conditional if var is nil' do
|
4
|
+
var = nil
|
5
|
+
expect(__var{}).to be_a(NilConditional)
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
context 'test method' do
|
10
|
+
before do
|
11
|
+
allow(::Object).to receive(:nil_test) { nil }
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'should return NilConditional instance when method return nil' do
|
15
|
+
expect(Object.nil_test).to be nil
|
16
|
+
expect(Object.new.__nil_test?).to be_a(NilConditional)
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should return NilConditional instance when method return nil and uses block' do
|
20
|
+
expect(Object.new.__nil_test?{}).to be_a(NilConditional)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/spec/object_spec.rb
CHANGED
@@ -1,25 +1,30 @@
|
|
1
1
|
describe Object do
|
2
2
|
context 'test method' do
|
3
|
-
it 'should
|
3
|
+
it 'should raise error when receiving test_method' do
|
4
4
|
expect { Object.new.test_method }.to raise_error(NoMethodError)
|
5
5
|
end
|
6
6
|
|
7
|
-
it 'should not raise error when receiving
|
8
|
-
expect { Object.new.
|
7
|
+
it 'should not raise error when receiving __test_method' do
|
8
|
+
expect { Object.new.__test_method }.to_not raise_error
|
9
9
|
end
|
10
10
|
|
11
|
-
it 'should return
|
12
|
-
expect(Object.new.
|
11
|
+
it 'should return NilConditional instance when received non existent method with preceding __' do
|
12
|
+
expect(Object.new.__test_method).to be_a(NilConditional)
|
13
13
|
end
|
14
14
|
|
15
15
|
it 'should support chained methods with nil conditional' do
|
16
|
-
expect { Object.new.
|
17
|
-
expect(Object.new.
|
16
|
+
expect { Object.new.__test_method.foo_?.bar_?.car_?.cow_? }.to_not raise_error
|
17
|
+
expect(Object.new.__test_method.foo_?.bar_?.car_?.cow_?).to be_a(NilConditional)
|
18
18
|
end
|
19
19
|
|
20
20
|
it 'should support methods with arguments' do
|
21
|
-
expect { Object.
|
22
|
-
expect(Object.
|
21
|
+
expect { Object.__test_method_with_args(1, 2, 3) }.to_not raise_error
|
22
|
+
expect(Object.__test_method_with_args(1, 2, 3)).to be_a(NilConditional)
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'should support methods with blocks' do
|
26
|
+
expect(Object.__test_method_with_block{ a = 'b' }).to be_a(NilConditional)
|
27
|
+
expect(['a', 'b'].__delete_if { |i| i == 'b' }).to eq([ 'a' ])
|
23
28
|
end
|
24
29
|
end
|
25
30
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nil_conditional
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Grzegorz Bizon
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-04-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -61,13 +61,16 @@ extra_rdoc_files: []
|
|
61
61
|
files:
|
62
62
|
- ".gitignore"
|
63
63
|
- ".rspec"
|
64
|
+
- ".travis.yml"
|
64
65
|
- Gemfile
|
65
66
|
- LICENSE.txt
|
66
67
|
- README.md
|
67
68
|
- Rakefile
|
68
69
|
- lib/nil_conditional.rb
|
69
|
-
- lib/nil_conditional/version.rb
|
70
70
|
- nil_conditional.gemspec
|
71
|
+
- spec/local_variables_spec.rb
|
72
|
+
- spec/nil_conditional_spec.rb
|
73
|
+
- spec/nil_spec.rb
|
71
74
|
- spec/object_spec.rb
|
72
75
|
- spec/spec_helper.rb
|
73
76
|
homepage: http://github.com/grzesiek/nil-conditional
|
@@ -90,11 +93,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
90
93
|
version: '0'
|
91
94
|
requirements: []
|
92
95
|
rubyforge_project:
|
93
|
-
rubygems_version: 2.4.
|
96
|
+
rubygems_version: 2.4.5
|
94
97
|
signing_key:
|
95
98
|
specification_version: 4
|
96
99
|
summary: Nil Conditional Operator in Ruby
|
97
100
|
test_files:
|
101
|
+
- spec/local_variables_spec.rb
|
102
|
+
- spec/nil_conditional_spec.rb
|
103
|
+
- spec/nil_spec.rb
|
98
104
|
- spec/object_spec.rb
|
99
105
|
- spec/spec_helper.rb
|
100
|
-
has_rdoc:
|