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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: cf1d6643060be57fa65e068058c18be67b556f43
4
- data.tar.gz: ea61686c2b12673eea19af37c53d893c2534fc4e
3
+ metadata.gz: 480a9c37b75244a79017defb5f87a09ec00bb4d2
4
+ data.tar.gz: c8ade086f96dccf7122da47898c418e923851579
5
5
  SHA512:
6
- metadata.gz: 93a0f182e484b1ddc80ac388a64c2dbc62a01e01673655bacb7f09d1ee55d16bbc4daa864862d27c23794d34fd523a2d2c6a366b17db29a7fe3bfcf07b937e50
7
- data.tar.gz: ebd9ee3c616386816517fccc54ab7c05d49461a40378a6ca1d33c2e6e94fd2f72de95a98d85d816078bb6a3eb5f595b4abea1252e7819ba82f813d107a97357e
6
+ metadata.gz: 4cecbcded18c99be80b8a9ba7e69cc11bc6d5eeee237b67f5013f4f8e3c43027ca5d8e18220aad045d22decba661a971d027a8dd65fcbab69a2bbb48cd5709d6
7
+ data.tar.gz: 40bb5fd2b473e6fdcd3635cdff15aba19d7c2007b373efbe64e770995276192a860329d8e7ebebc9de0f0bf283ee66cd7af12df2baaeddfecaa6718719ab894b
data/.gitignore CHANGED
@@ -12,3 +12,4 @@
12
12
  *.o
13
13
  *.a
14
14
  mkmf.log
15
+ .*.sw?
data/.travis.yml ADDED
@@ -0,0 +1,3 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.2.0
data/README.md CHANGED
@@ -2,49 +2,76 @@
2
2
 
3
3
  Nil Conditional Operator in Ruby.
4
4
 
5
- ## Summary
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
- Add this line to your application's Gemfile:
14
+ `nil_conditional` is gemified and available on RubyGems.
12
15
 
13
- ```ruby
14
- gem 'nil_conditional'
15
- ```
16
16
 
17
- And then execute:
17
+ ## Usage
18
18
 
19
- $ bundle
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
- Or install it yourself as:
22
+ ```ruby
22
23
 
23
- $ gem install nil_conditional
24
+ # logger is nil
25
+ logger.foo.bar.car.cow
26
+ NoMethodError: undefined method `foo` for #<NilClass>
24
27
 
25
- ## Usage
28
+ # logger is nil or doesn't exist
29
+ __logger{}.foo.bar.car.cow
30
+ => #<NilConditional>
26
31
 
27
- ```ruby
28
- empty_object = Object.new
29
- empty_object.non_existent_method_?
30
- => nil
32
+ # object exists and all methods are valid
33
+ __object{}.foo.bar.car.cow
34
+ => "moooo"
31
35
 
32
- empty_object_?
33
- => #<Object:0x00000002d89170>
36
+ # logger exists but doesn't have warn method
37
+ logger.__warn('some warning')
38
+ => #<NilConditional>
34
39
 
35
- non_existent_object_?
36
- => nil
40
+ __non_existent_local_variable{}
41
+ => #<NilConditional>
37
42
 
38
- "test_string".sub_?("_string", '_case')
39
- => "test_case"
43
+ __non_existent_method
44
+ => #<NilConditional>
40
45
 
41
- :test_string.sub_?("string", "case")
42
- => nil
46
+ Object.new.non_existent_method
47
+ NoMethodError: undefined method `non_existent_method` for #<Object>
43
48
 
44
- Object.foo_?.bar_?.car_?.cow_?
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.
@@ -1,17 +1,47 @@
1
- require "nil_conditional/version"
2
-
3
- module NilConditional
4
-
5
- class ::Object
6
- def method_missing(name, *params)
7
- if name =~ /^.+_\?$/
8
- original_method = name.to_s.sub(/_\?$/, '').to_sym
9
- return send(original_method, *params) if respond_to?(original_method)
10
- nil
11
- else
12
- super
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
@@ -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 = NilConditional::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 "rspec", "~> 3.2.0"
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 not raise error when receiving test_method_?' do
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 test_method_?' do
8
- expect { Object.new.test_method_? }.to_not raise_error
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 nil when received non existent method with nil conditional' do
12
- expect(Object.new.test_method_?).to be nil
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.test_method_?.foo_?.bar_?.car_?.cow_? }.to_not raise_error
17
- expect(Object.new.test_method_?.foo_?.bar_?.car_?.cow_?).to be nil
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.test_method_with_args_?(1, 2, 3) }.to_not raise_error
22
- expect(Object.test_method_with_args_?(1, 2, 3)).to be nil
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.1
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-03-15 00:00:00.000000000 Z
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.3
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:
@@ -1,3 +0,0 @@
1
- module NilConditional
2
- VERSION = "0.0.1"
3
- end