a_types 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: