corelib_ruby 0.0.2 → 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/CHANGELOG.md +7 -0
- data/README.md +5 -1
- data/lib/corelib_ruby/core_ext/array/base.rb +2 -0
- data/lib/corelib_ruby/core_ext/array/core.rb +17 -0
- data/lib/corelib_ruby/core_ext/array/delete.rb +2 -3
- data/lib/corelib_ruby/core_ext/array/iterators.rb +8 -0
- data/lib/corelib_ruby/core_ext/boolean/base.rb +2 -0
- data/lib/corelib_ruby/core_ext/boolean/false.rb +7 -0
- data/lib/corelib_ruby/core_ext/boolean/true.rb +7 -0
- data/lib/corelib_ruby/core_ext/hash/base.rb +2 -0
- data/lib/corelib_ruby/core_ext/hash/core.rb +7 -0
- data/lib/corelib_ruby/core_ext/hash/extract.rb +5 -7
- data/lib/corelib_ruby/core_ext/hash/iterators.rb +12 -0
- data/lib/corelib_ruby/core_ext/nil/base.rb +1 -0
- data/lib/corelib_ruby/core_ext/nil/core.rb +17 -0
- data/lib/corelib_ruby/core_ext/numeric/base.rb +1 -0
- data/lib/corelib_ruby/core_ext/numeric/core.rb +5 -0
- data/lib/corelib_ruby/core_ext/object/base.rb +1 -0
- data/lib/corelib_ruby/core_ext/object/core.rb +7 -0
- data/lib/corelib_ruby/core_ext/string/base.rb +2 -1
- data/lib/corelib_ruby/core_ext/string/conversions.rb +87 -2
- data/lib/corelib_ruby/core_ext/string/{accessors.rb → core.rb} +11 -7
- data/lib/corelib_ruby/core_ext/string/queries.rb +26 -0
- data/lib/corelib_ruby/core_ext/string/questions.rb +17 -4
- data/lib/corelib_ruby/version.rb +1 -1
- data/lib/corelib_ruby.rb +33 -2
- metadata +17 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e0e4a94e270cbb3cd956a2840be595c28a3739ad
|
4
|
+
data.tar.gz: 9802767a50bbee6e96ec08ed9933e59b6bec4434
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3c541ffa32cc75af1bb4217b9288f098ae19ea10d41cd2cd57d421fb0c84aee38bbcf22dd32d6127dbcce230e138be5750bad4a25ed1e6f95741ddefddb8de94
|
7
|
+
data.tar.gz: 32df6e615eb9dd90002efd77376b69d0838b7cf0f10a61a8d72d37fbee52f65e19959f4edf08a847999bae5533a591c5bd134ba617b6a27be8e4384c3598bf8e
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,12 @@
|
|
1
1
|
# CHANGELOG
|
2
2
|
|
3
|
+
## 1.0.0 (May 09, 2016)
|
4
|
+
|
5
|
+
1. (Change) Change method prefix to `cl_`. This is a major breaking change.
|
6
|
+
2. (New) Add optional method alias `_`.
|
7
|
+
3. (New) Add many new methods.
|
8
|
+
4. (New) Fill out test suite on methods.
|
9
|
+
|
3
10
|
## 0.0.2 (May 06, 2016)
|
4
11
|
|
5
12
|
1. (New) Add **Array** methods: `#co_delete!`
|
data/README.md
CHANGED
@@ -33,9 +33,13 @@ Or install it yourself as:
|
|
33
33
|
|
34
34
|
Browse the `/lib/corelib_ruby/` directory to find new methods; each method provides extensive document. All of these methods are now available inside your application without any additional configuration.
|
35
35
|
|
36
|
+
## Finding Methods
|
37
|
+
|
38
|
+
To find methods, read through the `lib/corelib_ruby/core_ext` folder.
|
39
|
+
|
36
40
|
## Conventions
|
37
41
|
|
38
|
-
All methods are prefixed with `
|
42
|
+
All methods are prefixed with `cl_` to help prevent collisions with other libraries and to make it clear that the method is not part of Ruby core. The unfortunate downside is it dirties up the up the method name. To help clean things up, all methods have a more simple alias of just `_`. For example, `String#cl_all_spaces?` is aliased to `String#_all_spaces?`. Use whichever strategy you like, but we recommend that you pick one and try to be consistent.
|
39
43
|
|
40
44
|
## Development
|
41
45
|
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class Array
|
2
|
+
# Many methods take an optional hash argument to hold options for the method. This method pops that hash off he arguments
|
3
|
+
# list if it exists or returns an empty hash.
|
4
|
+
def cl_extract_options!
|
5
|
+
last.is_a?(Hash) ? pop : {}
|
6
|
+
end
|
7
|
+
|
8
|
+
# A simple helper to improve readability.
|
9
|
+
# [].cl_not_empty? reads better than ![].empty?
|
10
|
+
def cl_not_empty?
|
11
|
+
!empty?
|
12
|
+
end
|
13
|
+
|
14
|
+
def cl_to_yes_no(options={})
|
15
|
+
collect {|e| e.cl_to_yes_no(options)}
|
16
|
+
end
|
17
|
+
end
|
@@ -1,9 +1,8 @@
|
|
1
1
|
class Array
|
2
|
-
#
|
3
|
-
# does not exist.
|
2
|
+
# Deletes items from the array, but raises an error if the item does not exist.
|
4
3
|
#
|
5
4
|
# obj: the obj to delete
|
6
|
-
def
|
5
|
+
def cl_delete!(obj)
|
7
6
|
# do this check first only if the obj is nil because the
|
8
7
|
# cost of include? rises linerarly with the size of the array
|
9
8
|
raise ArgumentError if obj.nil? && !include?(nil)
|
@@ -0,0 +1,8 @@
|
|
1
|
+
class Array
|
2
|
+
# Tterates over the Array just as you would with Array#each. However, for each iteration
|
3
|
+
# pass in an extra variable that will be `false` until the last iteration.
|
4
|
+
def cl_each_with_last_flag
|
5
|
+
my_size = size - 1
|
6
|
+
each_with_index {|item, index| yield(item, index == my_size)}
|
7
|
+
end
|
8
|
+
end
|
@@ -4,20 +4,18 @@ class Hash
|
|
4
4
|
#
|
5
5
|
# If key exists in the hash, it's value will be returned.
|
6
6
|
# If key doesn't exist, and optional default value will be returned
|
7
|
-
# If key doesn't exist and
|
7
|
+
# If key doesn't exist and no default is specified, a KeyError is raised
|
8
8
|
# If key doesn't exists, there is no default, but a block is given, then
|
9
9
|
# that block will be executed with the key.
|
10
|
-
def
|
10
|
+
def cl_extract(*args)
|
11
11
|
arg_length = args.length
|
12
12
|
fail ArgumentError, "wrong number of arguments #{arg_length} for 1..2" if arg_length == 0 || arg_length > 2
|
13
13
|
key = args[0]
|
14
14
|
|
15
|
-
if key
|
16
|
-
|
17
|
-
delete(key)
|
18
|
-
return val
|
19
|
-
end
|
15
|
+
# Just return the value if the key exists.
|
16
|
+
return delete(key) if key?(key)
|
20
17
|
|
18
|
+
# The key doesn't exist. If the user gave us a block, yield to it and return the value from the block.
|
21
19
|
return yield key if block_given?
|
22
20
|
(args.length == 2) ? args[1] : fail(KeyError, "key not found #{key.inspect}", caller)
|
23
21
|
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
class Hash
|
2
|
+
# Tterates over the Array just as you would with Array#each. However, for each iteration
|
3
|
+
# pass in an extra variable that will be `false` until the last iteration.
|
4
|
+
def cl_each_with_last_flag
|
5
|
+
my_size = size
|
6
|
+
index = 1
|
7
|
+
each_pair do |key, value|
|
8
|
+
yield(key, value, index == my_size)
|
9
|
+
index += 1
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require "corelib_ruby/core_ext/nil/core"
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class NilClass
|
2
|
+
# A simple helper to improve readability.
|
3
|
+
# [].cl_not_nil? reads better than ![].nil?
|
4
|
+
def cl_not_nil?
|
5
|
+
false
|
6
|
+
end
|
7
|
+
|
8
|
+
def cl_to_yes_no(options={})
|
9
|
+
options.fetch(:if_nil, "")
|
10
|
+
end
|
11
|
+
|
12
|
+
# See the documenation for String#cl_combine. This method exists so we can seamlessly call nil.cl_combine("foo") and get back
|
13
|
+
# "foo" (instead of an error).
|
14
|
+
def cl_combine(*args)
|
15
|
+
"".cl_combine(*args)
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require "corelib_ruby/core_ext/numeric/core"
|
@@ -0,0 +1 @@
|
|
1
|
+
require "corelib_ruby/core_ext/object/core"
|
@@ -1,6 +1,91 @@
|
|
1
1
|
class String
|
2
|
-
def
|
2
|
+
def cl_to_yes_no(options={})
|
3
|
+
self.cl_to_bool(options).cl_to_yes_no(options)
|
4
|
+
end
|
5
|
+
|
6
|
+
# Forces a string to have at least one leading space.
|
7
|
+
def cl_force_leading_space(even_when_empty: false)
|
3
8
|
(return even_when_empty ? " " : "") if empty?
|
4
|
-
|
9
|
+
cl_all_spaces? ? dup : " #{lstrip}"
|
10
|
+
end
|
11
|
+
|
12
|
+
# Convert a string to a boolean.
|
13
|
+
# true will always be returned if we can clearly match one of the true cases
|
14
|
+
# In unstrict mode, the string is assumed false if we cannot match true
|
15
|
+
# In strict mode, the string must clearly match a false condition to return false
|
16
|
+
# otherise an error is raised
|
17
|
+
def cl_to_bool(options={})
|
18
|
+
strip = options.fetch(:strip, true)
|
19
|
+
strict = options.fetch(:strict, false)
|
20
|
+
str = strip ? self.strip : self
|
21
|
+
return true if str =~ /\A(true|t|yes|y|1)\Z/i
|
22
|
+
|
23
|
+
if strict
|
24
|
+
return false if str.empty? || str =~ /\A(false|f|no|n|0)\Z/i
|
25
|
+
raise ArgumentError.new("cannot convert \"#{str}\" to boolean")
|
26
|
+
end
|
27
|
+
|
28
|
+
false
|
29
|
+
end
|
30
|
+
|
31
|
+
#Does the same thing as String#contact, but allows a separator to be inserted between the
|
32
|
+
#two strings.
|
33
|
+
def cl_concat_with(str, separator="")
|
34
|
+
return self if str.nil? || str.empty?
|
35
|
+
return self.concat(str) if self.empty?
|
36
|
+
self.concat(separator) unless separator.empty?
|
37
|
+
self.concat(str)
|
38
|
+
end
|
39
|
+
|
40
|
+
# Combines two strings together with a little more intelligence, using a separator. This methods reduces
|
41
|
+
# much of the prep you may need to do before concatenating two strings and allows you do do the concatenation on a single line.
|
42
|
+
# Examples
|
43
|
+
# "me".cl_combine("you") => "me you"
|
44
|
+
# " me ".cl_combine(" you", separator: "-") => "me-you"
|
45
|
+
# Options
|
46
|
+
# separator: The separate to place between the strings. (" " is the default)
|
47
|
+
# prefix: A string that should appear in front of the final concatenation (no default)
|
48
|
+
# suffix: A string that should appear at the end of the final concatenation (no default)
|
49
|
+
# wrap: A boolean which helps control whether or not the prefix and suffix should be added (true is the default)
|
50
|
+
# strip: Remove whitespace at the beginning and end of the strings before concatenating (true is the default)
|
51
|
+
# if_empty: An alternative string to return if the resulting concatenation is empty. This option is considered before the
|
52
|
+
# prefix or suffix is added. ("" is the default)
|
53
|
+
def cl_combine(*args)
|
54
|
+
options = args.cl_extract_options!
|
55
|
+
raise ArgumentError, "You need to supply at least one string" if args.empty?
|
56
|
+
str = self
|
57
|
+
args.each { |val| str = str.cl_private_combine(val, options) }
|
58
|
+
|
59
|
+
return options.fetch(:if_empty, "") if str.nil? || str.empty?
|
60
|
+
|
61
|
+
prefix = options.fetch(:prefix, nil)
|
62
|
+
str = "#{prefix}#{str}" if options.fetch(:wrap, true) && (prefix.cl_not_nil?)
|
63
|
+
suffix = options.fetch(:suffix, nil)
|
64
|
+
str = "#{str}#{suffix}" if options.fetch(:wrap, true) && (suffix.cl_not_nil?)
|
65
|
+
str
|
66
|
+
end
|
67
|
+
|
68
|
+
protected
|
69
|
+
|
70
|
+
def cl_private_combine(str, options={})
|
71
|
+
strip = options.fetch(:strip, true)
|
72
|
+
(return strip ? self.strip : self.dup) if str.nil? or str.empty?
|
73
|
+
(return strip ? str.strip : str.dup) if self.empty?
|
74
|
+
separator = options.fetch(:separator, " ")
|
75
|
+
|
76
|
+
if strip
|
77
|
+
pre = self.strip
|
78
|
+
post = str.strip
|
79
|
+
else
|
80
|
+
pre = self.dup
|
81
|
+
post = str.dup
|
82
|
+
end
|
83
|
+
|
84
|
+
return pre + post if separator.empty?
|
85
|
+
|
86
|
+
# TODO - Support other separators other than spaces. For instance if someone wanted to join with a comma
|
87
|
+
# and pre ended with a comma, we could have an option to disallow repeating
|
88
|
+
pre + separator + post
|
5
89
|
end
|
90
|
+
|
6
91
|
end
|
@@ -1,17 +1,21 @@
|
|
1
1
|
class String
|
2
|
-
def
|
2
|
+
def cl_not_empty?
|
3
|
+
!self.empty?
|
4
|
+
end
|
5
|
+
|
6
|
+
def cl_first
|
3
7
|
empty? ? "" : self[0, 1]
|
4
8
|
end
|
5
9
|
|
6
|
-
def
|
10
|
+
def cl_first_or_nil
|
7
11
|
empty? ? nil : self[0, 1]
|
8
12
|
end
|
9
13
|
|
10
|
-
def
|
14
|
+
def cl_last
|
11
15
|
empty? ? "" : self[-1, 1]
|
12
16
|
end
|
13
17
|
|
14
|
-
def
|
18
|
+
def cl_last_or_nil
|
15
19
|
empty? ? nil : self[-1, 1]
|
16
20
|
end
|
17
21
|
|
@@ -25,15 +29,15 @@ class String
|
|
25
29
|
# # => "This is ..."
|
26
30
|
# "This is a test".first_words(2, ellipses: " +++")
|
27
31
|
# # => "This is +++"
|
28
|
-
def
|
32
|
+
def cl_first_words(n=nil, ellipses: false)
|
29
33
|
new_str = n.nil? ? self : split[0...n].join(' ')
|
30
|
-
elip =
|
34
|
+
elip = cl_determine_ellipses(new_str, ellipses)
|
31
35
|
new_str + "#{elip}"
|
32
36
|
end
|
33
37
|
|
34
38
|
private
|
35
39
|
|
36
|
-
def
|
40
|
+
def cl_determine_ellipses(str, ellipses)
|
37
41
|
return "" if empty? || !ellipses
|
38
42
|
return "" if str == self
|
39
43
|
ellipses === true ? " ..." : ellipses.to_s
|
@@ -0,0 +1,26 @@
|
|
1
|
+
class String
|
2
|
+
#Returns the subset of a string from [0, position] if string[position] is a space.
|
3
|
+
#If string[max] is not a space, it is assumed we are in the middle of a word.
|
4
|
+
#and the logic will increase position a little bit to not break in the middle of a word.
|
5
|
+
def cl_excerpt_to_end_of_word(position=nil)
|
6
|
+
return self if position.nil? or position >= self.size
|
7
|
+
|
8
|
+
char = self[position]
|
9
|
+
return self[0, position].rstrip if char == " "
|
10
|
+
|
11
|
+
self[0, cl_index_of_next_space_from(position)].rstrip
|
12
|
+
end
|
13
|
+
|
14
|
+
#Given a position, return the position of the next space
|
15
|
+
def cl_index_of_next_space(position=0)
|
16
|
+
return nil if self.empty? or position.nil?
|
17
|
+
return nil if position >= self.size
|
18
|
+
|
19
|
+
idx = position
|
20
|
+
(self.size - position).times do
|
21
|
+
idx = idx + 1
|
22
|
+
return idx if self[idx] == " "
|
23
|
+
end
|
24
|
+
idx
|
25
|
+
end
|
26
|
+
end
|
@@ -1,10 +1,23 @@
|
|
1
1
|
class String
|
2
|
-
# Returns true if a non empty string contains all
|
3
|
-
# Tabs and new lines are not considered spaces.
|
2
|
+
# Returns true if a non empty string contains all space characters. Tabs and new lines are not considered spaces.
|
4
3
|
# Returns false for empty strings unless the when_empty: option is set to true.
|
5
|
-
def
|
4
|
+
def cl_all_spaces?(when_empty: false)
|
6
5
|
return when_empty if empty?
|
7
|
-
each_byte { |x| return false
|
6
|
+
each_byte { |x| return false if x != 32 }
|
8
7
|
true
|
9
8
|
end
|
9
|
+
|
10
|
+
# Returns true if a non empty string contains all digit characters. Tabs, new lines, line feeds and whitespace
|
11
|
+
# all cause the method to return false.
|
12
|
+
def cl_all_digits?(if_empty: false)
|
13
|
+
return if_empty if empty?
|
14
|
+
(self =~ /\A[0-9]+\z/).cl_not_nil?
|
15
|
+
end
|
16
|
+
|
17
|
+
# Returns true if a non empty string contains all letters. Tabs, new lines, line feeds and whitespace
|
18
|
+
# all cause the method to return false.
|
19
|
+
def cl_all_letters?(if_empty: false)
|
20
|
+
return if_empty if empty?
|
21
|
+
(self =~ /\A[[:alpha:]]+\z/).cl_not_nil?
|
22
|
+
end
|
10
23
|
end
|
data/lib/corelib_ruby/version.rb
CHANGED
data/lib/corelib_ruby.rb
CHANGED
@@ -1,7 +1,38 @@
|
|
1
1
|
require "corelib_ruby/version"
|
2
|
+
require "corelib_ruby/core_ext/nil/base"
|
3
|
+
require "corelib_ruby/core_ext/object/base"
|
4
|
+
require "corelib_ruby/core_ext/boolean/base"
|
5
|
+
require "corelib_ruby/core_ext/numeric/base"
|
2
6
|
require "corelib_ruby/core_ext/string/base"
|
3
7
|
require "corelib_ruby/core_ext/hash/base"
|
4
8
|
require "corelib_ruby/core_ext/array/base"
|
5
9
|
|
6
|
-
#
|
7
|
-
#
|
10
|
+
# Setup pry for development when running "rake console". Guard against load
|
11
|
+
# errors in production (since pry is only loaded as a DEVELOPMENT dependency
|
12
|
+
# in the .gemspec)
|
13
|
+
begin
|
14
|
+
require "pry"
|
15
|
+
rescue LoadError
|
16
|
+
end
|
17
|
+
|
18
|
+
module CorelibRuby
|
19
|
+
def self.prepare
|
20
|
+
[NilClass, Object, Array, String, FalseClass, TrueClass, Hash, Numeric].each do |class_name|
|
21
|
+
alias_methods_for_core_class(class_name)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# Alias any method starting with 'cl_' to a similiar method starting with '_'.
|
26
|
+
def self.alias_methods_for_core_class(class_name)
|
27
|
+
method_names = class_name.instance_methods.select {|m| m.to_s.start_with?("cl_") }
|
28
|
+
method_names.each do |method_name|
|
29
|
+
new_name = method_name.to_s
|
30
|
+
new_name.slice!(0, 3)
|
31
|
+
new_name = "_#{new_name}".to_sym
|
32
|
+
class_name.send(:alias_method, new_name, method_name)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
CorelibRuby.prepare
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: corelib_ruby
|
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
|
- roberts1000
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-05-
|
11
|
+
date: 2016-05-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -101,12 +101,26 @@ files:
|
|
101
101
|
- corelib_ruby.gemspec
|
102
102
|
- lib/corelib_ruby.rb
|
103
103
|
- lib/corelib_ruby/core_ext/array/base.rb
|
104
|
+
- lib/corelib_ruby/core_ext/array/core.rb
|
104
105
|
- lib/corelib_ruby/core_ext/array/delete.rb
|
106
|
+
- lib/corelib_ruby/core_ext/array/iterators.rb
|
107
|
+
- lib/corelib_ruby/core_ext/boolean/base.rb
|
108
|
+
- lib/corelib_ruby/core_ext/boolean/false.rb
|
109
|
+
- lib/corelib_ruby/core_ext/boolean/true.rb
|
105
110
|
- lib/corelib_ruby/core_ext/hash/base.rb
|
111
|
+
- lib/corelib_ruby/core_ext/hash/core.rb
|
106
112
|
- lib/corelib_ruby/core_ext/hash/extract.rb
|
107
|
-
- lib/corelib_ruby/core_ext/
|
113
|
+
- lib/corelib_ruby/core_ext/hash/iterators.rb
|
114
|
+
- lib/corelib_ruby/core_ext/nil/base.rb
|
115
|
+
- lib/corelib_ruby/core_ext/nil/core.rb
|
116
|
+
- lib/corelib_ruby/core_ext/numeric/base.rb
|
117
|
+
- lib/corelib_ruby/core_ext/numeric/core.rb
|
118
|
+
- lib/corelib_ruby/core_ext/object/base.rb
|
119
|
+
- lib/corelib_ruby/core_ext/object/core.rb
|
108
120
|
- lib/corelib_ruby/core_ext/string/base.rb
|
109
121
|
- lib/corelib_ruby/core_ext/string/conversions.rb
|
122
|
+
- lib/corelib_ruby/core_ext/string/core.rb
|
123
|
+
- lib/corelib_ruby/core_ext/string/queries.rb
|
110
124
|
- lib/corelib_ruby/core_ext/string/questions.rb
|
111
125
|
- lib/corelib_ruby/version.rb
|
112
126
|
homepage: https://github.com/corlewsolutions/corelib_ruby
|