a_types 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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 033d98d342a101aa3715d8da98b9b6f9c3740ca0
4
+ data.tar.gz: 24a52dba07f7c4fc9a0ecc319956899de80f5551
5
+ SHA512:
6
+ metadata.gz: 58b046a0a77041f24f3133aa377ae336f73e9e13e2204737e9bf557c3f34c861099d038d73122652da38f71ef21eb6de1bdbb8c0029ce642c0773726d05b7468
7
+ data.tar.gz: d04f7115599e89ada7d07d536c6e081e592161b2e27f54247c713072998e816b6aee6473062feaf7a7574ce62b7678931e0c0264b4bceaee7637d1169fba4e6d
@@ -0,0 +1,10 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ /.idea
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
@@ -0,0 +1,10 @@
1
+ Style/EmptyLines:
2
+ Enabled: false
3
+ Style/MethodName:
4
+ Enabled: false
5
+ Style/EmptyLinesAroundModuleBody:
6
+ Enabled: false
7
+ Style/EmptyLinesAroundClassBody:
8
+ Enabled: false
9
+ Style/SpaceInsideHashLiteralBraces:
10
+ Enabled: false
@@ -0,0 +1 @@
1
+ 2.3
@@ -0,0 +1,7 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0.0
4
+ - 2.1.5
5
+ - 2.2.3
6
+ - 2.3.0
7
+ before_install: gem install bundler -v 1.11.2
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in a_types.gemspec
4
+ gemspec
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 Yves Komenda
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,148 @@
1
+ [![Code Climate](https://codeclimate.com/github/Dervol03/a_types/badges/gpa.svg)](https://codeclimate.com/github/Dervol03/a_types)
2
+ [![Build Status](https://travis-ci.org/Dervol03/a_types.svg?branch=master)](https://travis-ci.org/Dervol03/a_types)
3
+
4
+ # ATypes (Advanced Data Types)
5
+
6
+ This gem provides some convenience methods to Ruby's basic data types which
7
+ are not present in ActiveSupport and especially offers some valuable Boolean
8
+ interpretation to Ruby's data types.
9
+
10
+ The gem comes in two flavors:
11
+ - core extensions, for those who prefer the handier addition of methods and
12
+ are sure they won't collide with others in their projects.
13
+ - decorators, for those who prefer to use the decorator pattern and prefer
14
+ to be really prudent about possible collisions in their project (i.e.
15
+ because they already use ActiveSupport and don't to risk it on version
16
+ updates)
17
+
18
+ You may also load both flavors, if you like, they don't collide.
19
+
20
+ ## Why another gem for advanced types?
21
+
22
+ While this gem has been inspired by others, like the [boolean
23
+ gem](https://rubygems.org/gems/boolean), these gems either have not been
24
+ updated for a very long time, don't go far enough or simply don't behave
25
+ really consistent in what they try to achieve.
26
+
27
+ Additionally, they often only provide logic for a single data type, which
28
+ tends to bloat one's Gemfile. Therefore, this gem unites different ideas, but
29
+ allow you to only load what you really want to use. See the [only take what
30
+ you need](#only-take-what-you-need) section.
31
+
32
+
33
+ ## Installation
34
+
35
+ Add this line to your application's Gemfile:
36
+
37
+ ```ruby
38
+ gem 'a_types'
39
+ ```
40
+
41
+ And then execute:
42
+
43
+ $ bundle
44
+
45
+ Or install it yourself as:
46
+
47
+ $ gem install a_types
48
+
49
+ ## Only take what you need
50
+
51
+ Similar to ActiveSupport, you won't get anything from simply requiring the
52
+ gem in your code.
53
+
54
+ ```ruby
55
+ require 'a_types'
56
+ ```
57
+
58
+ You have to specify which parts you wish to include in your project. Let's
59
+ assume you prefer the core extensions, then you may use following lines:
60
+
61
+ ```ruby
62
+
63
+ require 'a_types/core_ext/boolean' # => loads Boolean extensions
64
+ require 'a_types/core_ext/enumerable' # => loads Enumarable extensions
65
+ require 'a_types/core_ext/all' # => loads all core extentions
66
+ ```
67
+
68
+ You are more the decorator kind? This gem has exactly what you want:
69
+
70
+ ```ruby
71
+
72
+ require 'a_types/decorators/boolean' # => loads ATypes::Boolean decorator
73
+ require 'a_types/decorators/array' # => loads ATypes::Array decorator
74
+ require 'a_types/decorators/all' # => loads all available decorators
75
+ ```
76
+
77
+ You may also simply load everything in the gem, getting the core extension
78
+ AND the decorators:
79
+
80
+ ```ruby
81
+ require 'a_types/all'
82
+ ```
83
+
84
+
85
+ Feel free to browse the list of files which you may require on the [project's
86
+ homepage](https://github.com/Dervol03/a_types/tree/master/lib).
87
+
88
+ You may also find the documentation of each file there or on [rubygems.org]
89
+ (https://rubygems.org/gems/a_types).
90
+
91
+
92
+ ## Examples
93
+
94
+ ### Core extension
95
+
96
+ Loading the boolean extension will provide a `#to_bool` to any object.
97
+
98
+ ```ruby
99
+
100
+ require 'a_types/core_ext/boolean'
101
+
102
+ 'yes'.to_bool # => true
103
+ 'not positive'.to_bool! # => false
104
+ -1.to_bool # => false
105
+ 3.to_bool # => true
106
+ ```
107
+
108
+ ### Decorators
109
+
110
+ Loading the boolean decorator instead will provide a `Boolean` decorator
111
+ class. It provides an interpretation of truth to any provided object,
112
+ preserving its original behavior by delegation, as well.
113
+
114
+ ```ruby
115
+
116
+ require 'a_types/decorators/boolean'
117
+
118
+ b = ATypes::Boolean.new('yes')
119
+ b.content # => 'yes'
120
+ b.size # => 3
121
+
122
+ b.to_bool # => true
123
+ b.true? # => true
124
+ b.truthy? # => true
125
+
126
+ b2 = ATypes::Boolean.new('false')
127
+ b2.to_bool # => false
128
+ b2.true? # => falsse
129
+ b3.truthy? # => true
130
+ b2.falsey? # => false
131
+
132
+ bnil = ATypes::Boolean.new(nil)
133
+ bnil.to_bool # => false
134
+ bnil.true? # => false
135
+ bnil.truthy? # => false
136
+ bnil.falsey? # => true
137
+
138
+ ```
139
+
140
+ ## Contributing
141
+
142
+ Bug reports and pull requests are welcome on GitHub at https://github.com/Dervol03/a_types.
143
+
144
+
145
+ ## License
146
+
147
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
148
+
@@ -0,0 +1,6 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
@@ -0,0 +1,29 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'a_types/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'a_types'
8
+ spec.version = ATypes::VERSION
9
+ spec.authors = ['Yves Komenda']
10
+ spec.email = ['b_d_v@web.de']
11
+
12
+ spec.summary = "Provides advanced versions of Ruby's basic data types"
13
+ spec.description = "Provides advanced versions of Ruby's basic data types"
14
+ spec.homepage = 'https://github.com/Dervol03/a_types'
15
+ spec.license = 'MIT'
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
18
+ f.match(%r{^(spec)/})
19
+ end
20
+ spec.bindir = 'bin'
21
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
22
+ spec.require_paths = ['lib']
23
+
24
+ spec.add_development_dependency 'bundler', '~> 1.11'
25
+ spec.add_development_dependency 'rake', '~> 10.0'
26
+ spec.add_development_dependency 'rspec', '~> 3.0'
27
+ spec.add_development_dependency 'pry', '~> 0.10'
28
+ spec.add_development_dependency 'rubocop', '~> 0.36'
29
+ end
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'a_types.rb'
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require 'pry'
14
+ Pry.start
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,10 @@
1
+ require 'a_types/version'
2
+
3
+ support_dir = File.join(__dir__, 'a_types/support')
4
+ Dir[File.join(support_dir, '/**/*.rb')].each do |support_file|
5
+ require support_file
6
+ end
7
+
8
+ # Provides different convenience decorators following the decorator pattern.
9
+ module ATypes
10
+ end
@@ -0,0 +1,2 @@
1
+ require 'a_types/core_ext/all'
2
+ require 'a_types/decorators/all'
@@ -0,0 +1,3 @@
1
+ require 'a_types/core_ext/boolean'
2
+ require 'a_types/core_ext/enumerable'
3
+ require 'a_types/core_ext/numeric'
@@ -0,0 +1,115 @@
1
+ # This file adds the #to_bool method to numerous default classes of ruby,
2
+ # providing a more convenient of boolean handling to them. There are special
3
+ # cases for descendents of String and Numeric, all other objects will simply
4
+ # return their truthy-value according to Ruby's interpretation of truth.
5
+
6
+
7
+ # Adds #to_bool and #to_bool!
8
+ class Numeric
9
+ # Interprets this Numeric to a boolean value.
10
+ #
11
+ # @return [true, false] true if this is > 0, false otherwise.
12
+ def to_bool
13
+ self > 0 ? true : false
14
+ end
15
+ alias to_b to_bool
16
+ alias to_bool! to_bool
17
+ alias to_b! to_bool
18
+ end
19
+
20
+
21
+ # Adds #to_bool and #to_bool!
22
+ class String
23
+ # Converts this String to a boolean value.
24
+ # - Single characters are converted to _true_ if they are part of the set
25
+ # ['y', 'Y', '1']
26
+ #
27
+ # - Multiple characters are converted to _true_ if they are part of the set
28
+ # ['yes', 'Yes', 'YES', 'true', 'True', 'TRUE']
29
+ #
30
+ # - In any other case, the result will be false.
31
+ #
32
+ # @return [true, false] depending on the content.
33
+ def to_bool
34
+ %w(y Y 1 yes Yes YES true True TRUE).include?(self)
35
+ end
36
+ alias to_b to_bool
37
+
38
+
39
+ # Converts this String to a boolean value.
40
+ # - Single characters are converted to true if they are part of the set
41
+ # ['y', 'Y', '1']
42
+ #
43
+ # - Single characters are converted to _false_ if they are part of the set
44
+ # ['n', 'N', '0', '']
45
+ #
46
+ # - Multiple characters are converted to _true_ if they are part of the set
47
+ # ['yes', 'Yes', 'YES', 'true', 'True', 'TRUE']
48
+ #
49
+ # - Multiple characters are converted to _false_ if they are part of the set
50
+ # ['no', 'No', 'NO', 'false', 'False', 'FALSE']
51
+ #
52
+ # - In any other case, an ArgumentError will be raised.
53
+ #
54
+ # @return [true, false] depending on the content.
55
+ # @raise [ArgumentError] if this String is no real boolean value.
56
+ def to_bool!
57
+ return true if %w(y Y 1 yes Yes YES true True TRUE).include?(self)
58
+
59
+ negative = ['n', 'N', '0', 'no', 'No', 'NO', 'false', 'False', 'FALSE', '']
60
+ return false if negative.include?(self)
61
+
62
+ fail ArgumentError, "#{self} can't be interpreted as boolean!"
63
+ end
64
+ alias to_b! to_bool!
65
+ end
66
+
67
+
68
+ # Adds #to_bool and #to_bool!
69
+ class Object
70
+ # @return [true] respecting the Ruby way.
71
+ def to_bool
72
+ !nil?
73
+ end
74
+ alias to_b to_bool
75
+ alias to_bool! to_bool
76
+ alias to_b! to_bool
77
+ end
78
+
79
+
80
+
81
+ # Adds #to_bool and #to_bool!
82
+ class TrueClass
83
+ # @return [true] respecting the Ruby way.
84
+ def to_bool
85
+ self
86
+ end
87
+ alias to_b to_bool
88
+ alias to_bool! to_bool
89
+ alias to_b! to_bool
90
+ end
91
+
92
+
93
+ # Adds #to_bool and #to_bool!
94
+ class FalseClass
95
+ # @return [false] respecting the Ruby way.
96
+ def to_bool
97
+ self
98
+ end
99
+
100
+ alias to_b to_bool
101
+ alias to_bool! to_bool
102
+ alias to_b! to_bool
103
+ end
104
+
105
+
106
+ # Adds a Boolean cast method.
107
+ module Kernel
108
+ # Casts the given object to its boolean representation.
109
+ #
110
+ # @param [Object] obj_to_cast to be cast.
111
+ # @return [true, false] depending on the object.
112
+ def Boolean(obj_to_cast)
113
+ obj_to_cast.to_bool
114
+ end
115
+ end
@@ -0,0 +1,17 @@
1
+ # Adds #blank? if not already defined and #filled? as opposite method.
2
+ class Object
3
+ unless method_defined?(:blank?)
4
+ # Checks whether the object is nil or has no content.
5
+ #
6
+ # @return [true, false] depending on whether it is nil or empty.
7
+ def blank?
8
+ respond_to?(:empty?) ? empty? : nil?
9
+ end
10
+ end
11
+
12
+ # Checks whether the object has any content.
13
+ # @return [true, false] depending on whether any content is present.
14
+ def filled?
15
+ !blank?
16
+ end
17
+ end
@@ -0,0 +1,74 @@
1
+ # Provides convenience methods to convert objects into number representations
2
+ # . Most prominently #to_num method.
3
+
4
+ # Numeric additions.
5
+ class Object
6
+ # @return nil
7
+ def to_num
8
+ nil
9
+ end
10
+ end # Object
11
+
12
+
13
+ # Numeric Additions.
14
+ class Numeric
15
+ # Returns itself.
16
+ #
17
+ # @return [Numeric] itself.
18
+ def to_num
19
+ self
20
+ end
21
+ end # Numeric
22
+
23
+
24
+ # Numeric Additions.
25
+ class String
26
+ # Will convert any string with a valid number into the correct type (Fixnum
27
+ # or Float). If this String does not contain a valid number, nil will be
28
+ # returned.
29
+ #
30
+ # @return [Numeric, nil] depending on the value of this String.
31
+ def to_num
32
+ if self =~ /^-?\d+$/
33
+ to_i
34
+ elsif self =~ /^-?\d+[,.]\d+$/
35
+ sub(',', '.').to_f
36
+ end
37
+ end
38
+ end # String
39
+
40
+
41
+ # Numeric Additions.
42
+ class TrueClass
43
+ # @return 1
44
+ def to_num
45
+ 1
46
+ end
47
+ end
48
+
49
+
50
+ # Numeric Additions.
51
+ class FalseClass
52
+ # @return -1
53
+ def to_num
54
+ -1
55
+ end
56
+ end
57
+
58
+
59
+ # Numeric Additions.
60
+ class Array
61
+ # Tries to convert the joined result of this Array into a number. If this
62
+ # fails, nil is returned.
63
+ #
64
+ # @return [Numeric, nil] depending on whether joining returns a valid
65
+ # number String.
66
+ #
67
+ # @example
68
+ # [1,2,3,4].to_num # => 1234
69
+ # [1, '1.5', 6, 7].to_num # => 11.567
70
+ # [1, 'a', 2].to_num # => nil
71
+ def to_num
72
+ join.to_num
73
+ end
74
+ end # Array
@@ -0,0 +1,3 @@
1
+ require 'a_types/decorators/boolean_wrap'
2
+ require 'a_types/decorators/enuemrable_wrap'
3
+ require 'a_types/decorators/numeric_wrap'
@@ -0,0 +1,185 @@
1
+ require_relative 'wrapper'
2
+
3
+ module ATypes
4
+ # A decorator to any object providing Boolean behavior. In comparisons, it
5
+ # always returns the real true or false instance to avoid ambiguity. By
6
+ # default, it will handle special values for different object classes, like
7
+ # certain strings, e.g. transforming the *'true'* to an instance of the
8
+ # TrueClass. This behavior may be turned off, though, in which case the
9
+ # standard Ruby evaluation of truthy and falsey will be respected.
10
+ class BooleanWrap < Wrapper
11
+ # Extracts the truth from this BooleanWrap's value according to the
12
+ # following rules:
13
+ # - for any kind of numeric: values above *0* are *true*, others false.
14
+ #
15
+ # - for strings: any string equal to either of the following
16
+ # ["y", "Y", "1", "yes", "Yes", "YES", "true", "True", "TRUE"]
17
+ # will be *true*, any string equal to either of these
18
+ # ["n", "N", "-1", "no", "No", "NO", "false", "False", "FALSE"]
19
+ # will be *false*.
20
+ #
21
+ # - any other object will be transformed to a hard boolean according Ruby's
22
+ # default truthy evaluation.
23
+ #
24
+ # @return [true, false, nil] depending on whether the object may be
25
+ # converted and which value it contains.
26
+ def to_bool
27
+ @truth ||= extract_truth(content)
28
+ end
29
+ alias truth to_bool
30
+ alias to_b to_bool
31
+
32
+
33
+ # Will try to convert this BooleanWrap according to the rules of {#to_bool},
34
+ # however, it will raise an ArgumentError if conversion fails.
35
+ #
36
+ # @return [true, false, nil] depending on whether the object may be
37
+ # converted and which value it contains.
38
+ # @see #to_bool
39
+ def to_bool!
40
+ error_msg = ">#{content}< can't be interpreted as boolean!"
41
+ converted = to_bool
42
+
43
+ fail(ArgumentError, error_msg) if converted.nil?
44
+ converted
45
+ end
46
+
47
+
48
+ # @return [true, false] depending on whether the content interprets to true.
49
+ def true?
50
+ to_bool
51
+ end
52
+
53
+
54
+ # @return [true, false] depending on whether the content interprets to
55
+ # false.
56
+ def false?
57
+ !to_bool
58
+ end
59
+
60
+
61
+ # @return [true, false] whether the content is truthy according to Ruby's
62
+ # rules.
63
+ def truthy?
64
+ # content can literally be ANYTHING, thus double negation should be the
65
+ # tool of choice here.
66
+ !!content
67
+ end
68
+
69
+
70
+ # @return [true, false] whether the content is falsey according to Ruby's
71
+ # rules.
72
+ def falsey?
73
+ !content
74
+ end
75
+
76
+
77
+ # Will operate a logical AND with other, based on this BooleanWrap's
78
+ # {#to_bool} interpretation. It will therefore handle Ruby's native booleans
79
+ # and the BooleanWrap instances in the very same way. Otherwise, the logic
80
+ # abides Ruby's default truthy interpretation.
81
+ #
82
+ # @example
83
+ # BooleanWrap.new(true) & BooleanWrap.new(true) # => true
84
+ # BooleanWrap.new('y') & "hello" # => true
85
+ # BooleanWrap.new('y') & nil # => false
86
+ #
87
+ # @param [BooleanWrap, true, false, Object] other to logically combine with
88
+ # this BooleanWrap.
89
+ # @return [true, false] result of logical AND.
90
+ def &(other)
91
+ other_value = other.respond_to?(:truthy?) ? other.truthy? : other
92
+ to_bool & other_value
93
+ end
94
+
95
+
96
+ # Will operate a logical OR with other, based on this BooleanWrap's
97
+ # {#to_bool} interpretation. It will therefore handle Ruby's native booleans
98
+ # and the BooleanWrap instances in the very same way. Otherwise, the logic
99
+ # abides Ruby's default truthy interpretation.
100
+ #
101
+ # @example
102
+ # BooleanWrap.new(true) | BooleanWrap.new(true) # => true
103
+ # BooleanWrap.new('y') | "hello" # => true
104
+ # BooleanWrap.new('y') | nil # => true
105
+ # BooleanWrap.new(false) | nil # => false
106
+ #
107
+ # @param [BooleanWrap, true, false, Object] other to logically combine with
108
+ # this BooleanWrap.
109
+ # @return [true, false] result of logical OR.
110
+ def |(other)
111
+ other_value = other.respond_to?(:truthy?) ? other.truthy? : other
112
+ to_bool | other_value
113
+ end
114
+
115
+
116
+ # Will operate a logical XOR with other, based on this BooleanWrap's
117
+ # {#to_bool} interpretation. It will therefore handle Ruby's native booleans
118
+ # and the BooleanWrap instances in the very same way. Otherwise, the logic
119
+ # abides Ruby'sdefault truthy interpretation.
120
+ #
121
+ # @example
122
+ # BooleanWrap.new(true) ^ BooleanWrap.new(true) # => false
123
+ # BooleanWrap.new('y') ^ "hello" # => true
124
+ # BooleanWrap.new('y') ^ nil # => true
125
+ # BooleanWrap.new(false) ^ nil # => false
126
+ #
127
+ # @param [BooleanWrap, true, false, Object] other to logically combine with
128
+ # this BooleanWrap.
129
+ # @return [true, false] result of logical OR.
130
+ def ^(other)
131
+ other_value = other.respond_to?(:truthy?) ? other.truthy? : other
132
+ to_bool ^ other_value
133
+ end
134
+
135
+
136
+ # @example
137
+ # BooleanWrap.new('y').to_s # => "true"
138
+ #
139
+ # @return [String] string representation of this BooleanWrap's {#to_bool}
140
+ # interpretation.
141
+ def to_s
142
+ to_bool.to_s
143
+ end
144
+ alias inspect to_s
145
+
146
+
147
+ # Will try to convert given object to a boolean value according to
148
+ # {#to_bool!}. If this fails, it will return nil.
149
+ #
150
+ # @param [Object] source to be converted to a boolean value.
151
+ # @return [true, false, nil] depending on whether and how the object is
152
+ # convertible
153
+ def self.try_convert(source)
154
+ new(source).to_bool!
155
+ end
156
+
157
+ private
158
+
159
+ def convert_string(obj)
160
+ if %w(y Y 1 yes Yes YES true True TRUE).include?(obj)
161
+ true
162
+ elsif %w(n N -1 no No NO false False FALSE).include?(obj)
163
+ false
164
+ end
165
+ end
166
+
167
+ def convert_numeric(value)
168
+ value > 0
169
+ end
170
+
171
+ alias convert_fixnum convert_numeric
172
+ alias convert_integer convert_numeric
173
+ alias convert_bignum convert_numeric
174
+ alias convert_float convert_numeric
175
+ alias convert_bigdecimal convert_numeric
176
+
177
+
178
+ def extract_truth(obj)
179
+ strategy = "convert_#{obj.class.name.downcase}"
180
+ @truth = respond_to?(strategy, true) ? send(strategy, obj) : truthy?
181
+ end
182
+
183
+
184
+ end # BooleanWrap
185
+ end # ATypes
@@ -0,0 +1,24 @@
1
+ module ATypes
2
+ # Adds enumerable convenience methods to any object, preserving its original
3
+ # behavior.
4
+ class EnumerableWrap < Wrapper
5
+ # Returns true if this objects contains any actual content.
6
+ #
7
+ # @return [true, false] depending on whether this object has content.
8
+ def filled?
9
+ !blank?
10
+ end
11
+
12
+
13
+ # Checks whether the object is nil or empty.
14
+ #
15
+ # @return [true, false] if object is empty or nil.
16
+ def blank?
17
+ if content.respond_to?(:empty?)
18
+ content.empty?
19
+ else
20
+ content.nil?
21
+ end
22
+ end
23
+ end # EnumerableWrap
24
+ end # ATypes
@@ -0,0 +1,67 @@
1
+ require_relative 'wrapper'
2
+
3
+ module ATypes
4
+ # Adds numeric methods to any wrapped object.
5
+ class NumericWrap < Wrapper
6
+ # Returns the numeric value of this wrapped object. Depending on its class,
7
+ # different strategies will be applied in the course:
8
+ # - Strings will be parsed for their content and return nil if it does not
9
+ # match any number
10
+ # - true/false will return 1 / -1
11
+ # - Numerics will return themselves
12
+ # - Other objects will simply return nil
13
+ #
14
+ # @return [Fixnum, Float, nil] the number that could be interpreted from the
15
+ # wrapped object.
16
+ def to_num
17
+ strategy = "convert_#{content.class.name.downcase}"
18
+ respond_to?(strategy, true) ? send(strategy, content) : nil
19
+ end
20
+
21
+
22
+ # Tries to convert the given object to a numerical value, according to the
23
+ # rules of {#to_num}. Returns nil if no conversion is possible.
24
+ #
25
+ # @param [Object] source to be converted
26
+ # @return [Fixnum, Float, nil] the result of the conversion to a numeric
27
+ # value.
28
+ def self.try_convert(source)
29
+ new(source).to_num
30
+ end
31
+
32
+ private
33
+
34
+ def convert_string(content)
35
+ if content =~ Matchers::FIXNUM
36
+ content.to_i
37
+ elsif content =~ Matchers::FLOAT
38
+ content.sub(',', '.').to_f
39
+ end
40
+ end
41
+
42
+
43
+ def convert_trueclass(_content)
44
+ 1
45
+ end
46
+
47
+
48
+ def convert_falseclass(_content)
49
+ -1
50
+ end
51
+
52
+
53
+ def convert_array(content)
54
+ convert_string(content.join)
55
+ end
56
+
57
+
58
+ def convert_fixnum(content)
59
+ content
60
+ end
61
+ alias convert_bignum convert_fixnum
62
+ alias convert_numeric convert_fixnum
63
+ alias convert_integer convert_fixnum
64
+ alias convert_float convert_fixnum
65
+ alias convert_bigdecimal convert_fixnum
66
+ end # NumericWrap
67
+ end # ATypes
@@ -0,0 +1,9 @@
1
+ module ATypes
2
+ # Parent class of all wrappers.
3
+ class Wrapper < SimpleDelegator
4
+ # @return [Object] original object.
5
+ def content
6
+ __getobj__
7
+ end
8
+ end # Wrapper
9
+ end
@@ -0,0 +1,10 @@
1
+ module ATypes
2
+ # Provides common matchers
3
+ module Matchers
4
+ # Regular expression representing a Fixnum.
5
+ FIXNUM = /^-?\d+$/
6
+ # Regular expression matching any float, independently from the separating
7
+ # character.
8
+ FLOAT = /^-?\d+[,.]\d+$/
9
+ end # Matchers
10
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ATypes
4
+ VERSION = '1.0.0'.freeze
5
+ end
metadata ADDED
@@ -0,0 +1,142 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: a_types
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Yves Komenda
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-03-05 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.11'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.11'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: pry
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '0.10'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '0.10'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rubocop
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '0.36'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '0.36'
83
+ description: Provides advanced versions of Ruby's basic data types
84
+ email:
85
+ - b_d_v@web.de
86
+ executables:
87
+ - console
88
+ - setup
89
+ extensions: []
90
+ extra_rdoc_files: []
91
+ files:
92
+ - ".gitignore"
93
+ - ".rspec"
94
+ - ".rubocop.yml"
95
+ - ".ruby-version"
96
+ - ".travis.yml"
97
+ - Gemfile
98
+ - LICENSE.txt
99
+ - README.md
100
+ - Rakefile
101
+ - a_types.gemspec
102
+ - bin/console
103
+ - bin/setup
104
+ - lib/a_types.rb
105
+ - lib/a_types/all.rb
106
+ - lib/a_types/core_ext/all.rb
107
+ - lib/a_types/core_ext/boolean.rb
108
+ - lib/a_types/core_ext/enumerable.rb
109
+ - lib/a_types/core_ext/numeric.rb
110
+ - lib/a_types/decorators/all.rb
111
+ - lib/a_types/decorators/boolean_wrap.rb
112
+ - lib/a_types/decorators/enuemrable_wrap.rb
113
+ - lib/a_types/decorators/numeric_wrap.rb
114
+ - lib/a_types/decorators/wrapper.rb
115
+ - lib/a_types/support/matchers.rb
116
+ - lib/a_types/version.rb
117
+ homepage: https://github.com/Dervol03/a_types
118
+ licenses:
119
+ - MIT
120
+ metadata: {}
121
+ post_install_message:
122
+ rdoc_options: []
123
+ require_paths:
124
+ - lib
125
+ required_ruby_version: !ruby/object:Gem::Requirement
126
+ requirements:
127
+ - - ">="
128
+ - !ruby/object:Gem::Version
129
+ version: '0'
130
+ required_rubygems_version: !ruby/object:Gem::Requirement
131
+ requirements:
132
+ - - ">="
133
+ - !ruby/object:Gem::Version
134
+ version: '0'
135
+ requirements: []
136
+ rubyforge_project:
137
+ rubygems_version: 2.5.1
138
+ signing_key:
139
+ specification_version: 4
140
+ summary: Provides advanced versions of Ruby's basic data types
141
+ test_files: []
142
+ has_rdoc: