nil_conditional 0.0.1 → 1.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 -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:
|