dm_ruby_extensions 1.0.9 → 1.6.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
- SHA1:
3
- metadata.gz: faf35d14eb0e9a4fd037b1e3b3aed616141a0cb4
4
- data.tar.gz: 3419c2d7b07edcc1dcf0c5c5a3bcd0abb1d6a4c7
2
+ SHA256:
3
+ metadata.gz: 36e22b14857c9ce862d6610260ebf28c314982649a0a69e6e04cf37bd74fad25
4
+ data.tar.gz: 1002cd447ad89971c298c3eeb3f21069302491667781546c82de05b28beb3521
5
5
  SHA512:
6
- metadata.gz: ff6026e4c21a2adc2238854c7ac1623bd6d8931ff9ecbab07bb7b4b535b28885bca80f568b1d2445f313c3ec29a3a46cce147f85143db802b274f0b02eddd54c
7
- data.tar.gz: b2ff730e615af076f516718e68ad5f6f2a08467f327146c7b446c6e76c99be09b7652c79162c13df645463d735bcddf070727d115aa6f71ca3984beca6f6f230
6
+ metadata.gz: 60992cd05bf21a44458666b8bdd8d6e6e91360c53f259f930421b05ed1701b0e9f6b028c28842793007be1312e9c28a6036de6b5484ccae3a967b0a692b311bf
7
+ data.tar.gz: 52bf4954ecfcd7a36f1efb02a4b5fd72e671242ce5df1c95ae96b2150915b3b61abfbd4aec5fc53df9af512ec80d4a031b6c4d6cb90168590f6dfba5c8c6886f
data/CHANGELOG.md ADDED
@@ -0,0 +1,19 @@
1
+ # Changelog
2
+
3
+ ## 1.6.0
4
+
5
+ - Support Ruby 4.0: `required_ruby_version` is now `>= 3.2` (was `~> 3.0`, which
6
+ excluded Ruby 4).
7
+ - Drop support for Ruby 3.0 and 3.1, which have reached end of life.
8
+ - Limit ActiveSupport to `>= 6.0, < 9`.
9
+ - Gemspec: package files with `Dir` instead of `git ls-files`, remove the
10
+ deprecated `test_files`, require MFA for publishing, and add source, changelog
11
+ and bug tracker links.
12
+ - Replace the Travis build, which no longer ran, with GitHub Actions on Ruby 3.2
13
+ through 4.0.
14
+ - Update RuboCop to 1.92 and rubocop-rspec to 3.10.
15
+ - Fix a spec for `nil + other` that didn't actually test it.
16
+
17
+ ## 1.5.0
18
+
19
+ - Drop support for Ruby 2.
data/README.md CHANGED
@@ -1,92 +1,146 @@
1
1
  # DmRubyExtensions
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/dm_ruby_extensions.svg)](http://badge.fury.io/rb/dm_ruby_extensions)
4
- [![Build Status](https://travis-ci.com/digitalmoksha/dm_ruby_extensions.svg?branch=master)](https://travis-ci.com/digitalmoksha/dm_ruby_extensions)
4
+ [![Build status](https://github.com/digitalmoksha/dm_ruby_extensions/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/digitalmoksha/dm_ruby_extensions/actions/workflows/ci.yml)
5
5
 
6
- Adds some simple convienence methods to some Ruby classes, for use in the digitalMoksha gems. Although some of these can be found in other libraries, this includes a small handful and removes the dependency on another large library.
6
+ A small set of convenience methods added to Ruby's core classes (`String`, `Hash`,
7
+ `Array`, `Date` and others). It's used by the digitalMoksha gems, such as
8
+ [moksha_cms](https://gitlab.com/moksha_cms/moksha_cms), for formatting names and
9
+ titles, building CSS and URLs, reading Rails date params, and similar everyday jobs.
7
10
 
8
- ## Installation
9
-
10
- Add this line to your application's Gemfile:
11
-
12
- gem 'dm_ruby_extensions'
13
-
14
- And then execute:
15
-
16
- $ bundle
17
-
18
- Or install it yourself as:
19
-
20
- $ gem install dm_ruby_extensions
21
-
22
- ## Usage
23
-
24
- #### Array
25
-
26
- * extract_options!
27
- * closest_max
28
- * xss_aware_join
29
- * css_join
30
-
31
- #### Date
32
-
33
- * to_age
34
- * localize
11
+ ## Requirements
35
12
 
36
- #### DateTime
13
+ - Ruby 3.2 or later (CI covers 3.2 through 4.0)
14
+ - ActiveSupport 6.0 or later
37
15
 
38
- * to_age
39
- * localize
16
+ Requiring the gem also loads `active_support/core_ext`. The `localize` methods use
17
+ `I18n`, which comes with ActiveSupport.
40
18
 
41
- #### Fixnum
42
-
43
- * factorial
44
- * as_boolean
45
-
46
- #### Hash
47
-
48
- * convert_date
49
- * convert_datetime
50
- * url_query_string
51
- * rekey
52
- * rekey!
53
-
54
- #### Nil
55
-
56
- * to_s_default
57
- * as_boolean
58
- * to_age
59
- * sql_wildcard
60
-
61
- #### Numeric
62
-
63
- * percent_of
64
-
65
- #### String
66
-
67
- * to_s_default
68
- * as_boolean
69
- * as_css_size
70
- * sql_wildcard
71
- * replace_non_alphanumeric
72
- * expand_url
73
- * absolute_url?
74
- * smart_titlecase
75
- * smart_capitalize
76
- * smart_capitalize!
77
- * smart_truncate
78
- * name_case
79
- * name_case!
19
+ ## Installation
80
20
 
81
- #### Time
21
+ Add it to your Gemfile:
22
+
23
+ ```ruby
24
+ gem 'dm_ruby_extensions'
25
+ ```
26
+
27
+ and run `bundle install`. In a Rails app it's loaded by Bundler; elsewhere, add
28
+ `require 'dm_ruby_extensions'`.
29
+
30
+ ## What it adds
31
+
32
+ ### String
33
+
34
+ | Method | Description |
35
+ |---|---|
36
+ | `to_s_default(default = 'n/a')` | The string, or `default` if it's empty or only whitespace |
37
+ | `as_boolean` | `true` for `'true'`, `'yes'` or `'1'`, otherwise `false` |
38
+ | `as_css_size` | Adds `px` unless the value already has `px`, `%` or `em`, or is `auto`/`inherit` |
39
+ | `sql_wildcard` | Wraps the string in `%` for a SQL `LIKE` |
40
+ | `replace_non_alphanumeric(replacement = '')` | Replaces everything except letters, digits, `_`, `.` and `-` |
41
+ | `sanitize_filename` | Strips any path (Unix or Windows) and replaces unsafe characters with `_` |
42
+ | `expand_url(path = '')` | Prefixes a relative URL with `path`; absolute URLs are returned unchanged |
43
+ | `absolute_url?` | `true` if the string contains `://` or starts with `/` |
44
+ | `smart_titlecase` | Title case that keeps small words lowercase (Ruby port of John Gruber's TitleCase) |
45
+ | `smart_capitalize` / `smart_capitalize!` | Capitalizes the first real letter, leaving words like `iPhone` alone |
46
+ | `smart_truncate(words: 12)` / `smart_truncate(sentences: n)` | Truncates by words or sentences and appends `...` |
47
+ | `name_case` / `name_case!` | Properly cases names, e.g. `McDonald`, `O'Brien` (port of Lingua::EN::NameCase) |
48
+
49
+ ```ruby
50
+ '300'.as_css_size #=> "300px"
51
+ 'images/logo.png'.expand_url('/assets') #=> "/assets/images/logo.png"
52
+ 'C:\docs\my report.pdf'.sanitize_filename #=> "my_report.pdf"
53
+ 'the lord of the rings'.smart_titlecase #=> "The Lord of the Rings"
54
+ 'one two three four five'.smart_truncate(words: 3) #=> "one two three..."
55
+ 'MCDONALD'.name_case #=> "McDonald"
56
+ ```
57
+
58
+ ### Hash
59
+
60
+ | Method | Description |
61
+ |---|---|
62
+ | `convert_date(attribute)` | Builds a `Date` from Rails date-select params (`attr(1i)`–`attr(3i)`), or `nil` |
63
+ | `convert_datetime(attribute)` | Builds a local `Time` from Rails datetime-select params (`attr(1i)`–`attr(5i)`), or `nil` |
64
+ | `url_query_string(leading_slash = true)` | Turns the hash into a query string, e.g. `"/?page=2&q=yoga"` |
65
+ | `rekey` / `rekey!` | Renames keys with a key map or a block; with neither, symbolizes all keys (from [Facets](https://github.com/rubyworks/facets)) |
66
+
67
+ ```ruby
68
+ params = { 'start_date(1i)' => '2026', 'start_date(2i)' => '11', 'start_date(3i)' => '8' }
69
+ params.convert_date(:start_date) #=> Sun, 08 Nov 2026
70
+ { page: 2, q: 'yoga' }.url_query_string #=> "/?page=2&q=yoga"
71
+ { a: 1, b: 2 }.rekey(a: 'x') # 'x' => 1, :b => 2
72
+ ```
73
+
74
+ ### Array
75
+
76
+ | Method | Description |
77
+ |---|---|
78
+ | `extract_options!` | Removes and returns a trailing options hash, or `{}` |
79
+ | `closest_max(value)` | The largest element that is less than or equal to `value` |
80
+ | `xss_aware_join(delimiter = '')` | Joins into an `html_safe` string, escaping elements that aren't already safe |
81
+ | `css_join` | Joins CSS class names, skipping `nil` and empty strings; returns `nil` if nothing is left, so Rails leaves the attribute out |
82
+
83
+ ```ruby
84
+ [0, 5, 7, 8, 11, 16].closest_max(6) #=> 5
85
+ ['btn', nil, '', 'btn-primary'].css_join #=> "btn btn-primary"
86
+ [nil, ''].css_join #=> nil
87
+ ```
88
+
89
+ ### Date, DateTime and Time
90
+
91
+ | Method | Description |
92
+ |---|---|
93
+ | `Date#to_age`, `DateTime#to_age` | Age in whole years, e.g. from a birth date |
94
+ | `Date#to_index`, `DateTime#to_index` | A sortable integer for the day: day of year + (year − 2000) × 1000 |
95
+ | `localize(options = {})` | `I18n.localize(self, ...)`; a string argument is taken as the `format` |
96
+
97
+ ### Numbers and booleans
98
+
99
+ | Method | Description |
100
+ |---|---|
101
+ | `Integer#factorial` | `5.factorial #=> 120` |
102
+ | `Integer#as_boolean` | `true` for positive numbers, otherwise `false` |
103
+ | `Numeric#percent_of(total, precision = 0)` | `25.percent_of(80) #=> 31`; returns `0` when `total` is zero |
104
+ | `TrueClass#as_boolean`, `FalseClass#as_boolean` | Return themselves, so `as_boolean` works on any of these values |
105
+
106
+ ### nil
107
+
108
+ `nil` gets the same helpers, so you don't have to check for it first:
109
+
110
+ | Method | Returns |
111
+ |---|---|
112
+ | `to_s_default(default = 'n/a')` | `default` |
113
+ | `as_boolean` | `false` |
114
+ | `to_age` | `0` |
115
+ | `sql_wildcard` | `'%'` (matches everything) |
116
+ | `utc` | `''` |
117
+ | `+(other)` | `other`, so `nil + 5 #=> 5` |
118
+
119
+ ## Development
120
+
121
+ ```
122
+ bundle install
123
+ bundle exec rspec
124
+ bundle exec rubocop
125
+ ```
126
+
127
+ CI runs the specs on Ruby 3.2 through 4.0 (plus ruby-head) on Linux and macOS, and
128
+ runs RuboCop, for every pull request and push to `master`.
129
+
130
+ To release a new version, update `lib/dm_ruby_extensions/version.rb` and
131
+ `CHANGELOG.md`, then:
132
+
133
+ ```
134
+ gem build dm_ruby_extensions.gemspec
135
+ gem push dm_ruby_extensions-<version>.gem
136
+ ```
82
137
 
83
- * localize
138
+ ## Contributing
84
139
 
140
+ Bug reports and pull requests are welcome at
141
+ <https://github.com/digitalmoksha/dm_ruby_extensions>. Please include specs for any
142
+ change.
85
143
 
86
- ## Contributing
144
+ ## License
87
145
 
88
- 1. Fork it
89
- 2. Create your feature branch (`git checkout -b my-new-feature`)
90
- 3. Commit your changes (`git commit -am 'Add some feature'`)
91
- 4. Push to the branch (`git push origin my-new-feature`)
92
- 5. Create new Pull Request
146
+ MIT. See [LICENSE](LICENSE).
@@ -1,7 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  #------------------------------------------------------------------------------
2
4
  class Array
3
-
4
- # Extract options from a set of arguments. Removes and returns the last element in the array if it's a hash, otherwise returns a blank hash.
5
+ # Extract options from a set of arguments. Removes and returns the last element
6
+ # in the array if it's a hash, otherwise returns a blank hash.
5
7
  #
6
8
  # def options(*args)
7
9
  # args.extract_options!
@@ -19,7 +21,7 @@ class Array
19
21
  # [0,5,7,8,11,16].closest_max(7) => 7
20
22
  #------------------------------------------------------------------------------
21
23
  def closest_max(value)
22
- self.select{|item| item <= value}.max
24
+ self.select { |item| item <= value }.max
23
25
  end
24
26
 
25
27
  # able to join safe and unsafe strings
@@ -27,7 +29,7 @@ class Array
27
29
  def xss_aware_join(delimiter = '')
28
30
  ''.html_safe.tap do |str|
29
31
  each_with_index do |element, i|
30
- str << delimiter if i > 0
32
+ str << delimiter if i.positive?
31
33
  str << element
32
34
  end
33
35
  end
@@ -38,8 +40,8 @@ class Array
38
40
  # is an empty string (rails tag methods will not include the
39
41
  # attribute if it is nil, which is desirable for cleaner html)
40
42
  #------------------------------------------------------------------------------
41
- def css_join(delimiter = '')
42
- str = self.flatten.delete_if {|x| x.nil? || x == ''}.join(' ')
43
+ def css_join(_delimiter = '')
44
+ str = flatten.delete_if { |x| x.nil? || x == '' }.join(' ')
43
45
  str == '' ? nil : str
44
46
  end
45
47
  end
@@ -1,23 +1,22 @@
1
- class Date
1
+ # frozen_string_literal: true
2
2
 
3
+ class Date
3
4
  # http://stackoverflow.com/questions/819263/get-persons-age-in-ruby
4
5
  #------------------------------------------------------------------------------
5
6
  def to_age
6
7
  now = Time.now.utc.to_date
7
- now.year - self.year - ((now.month > self.month || (now.month == self.month && now.day >= self.day)) ? 0 : 1)
8
+ now.year - year - (now.month > month || (now.month == month && now.day >= day) ? 0 : 1)
8
9
  end
9
-
10
+
10
11
  #------------------------------------------------------------------------------
11
12
  def localize(options = {})
12
- options = {:format => options} if options.class == String
13
- I18n.localize(self, options)
13
+ options = { format: options } if options.instance_of?(String)
14
+ I18n.localize(self, **options)
14
15
  end
15
16
 
16
17
  # Create a unique sortable index for this date
17
18
  #------------------------------------------------------------------------------
18
19
  def to_index
19
- yday + (year-2000) * 1000
20
+ yday + ((year - 2000) * 1000)
20
21
  end
21
-
22
22
  end
23
-
@@ -1,6 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  #------------------------------------------------------------------------------
2
4
  class DateTime
3
-
4
5
  #------------------------------------------------------------------------------
5
6
  def to_age
6
7
  (DateTime.now - self).to_i / 365
@@ -8,15 +9,13 @@ class DateTime
8
9
 
9
10
  #------------------------------------------------------------------------------
10
11
  def localize(options = {})
11
- options = {:format => options} if options.class == String
12
- I18n.localize(self, options)
12
+ options = { format: options } if options.instance_of?(String)
13
+ I18n.localize(self, **options)
13
14
  end
14
-
15
+
15
16
  # Create a unique sortable index for this date
16
17
  #------------------------------------------------------------------------------
17
18
  def to_index
18
- yday + (year-2000) * 1000
19
+ yday + ((year - 2000) * 1000)
19
20
  end
20
-
21
21
  end
22
-
@@ -1,8 +1,7 @@
1
- class FalseClass #:nodoc:
1
+ # frozen_string_literal: true
2
2
 
3
+ class FalseClass # :nodoc:
3
4
  def as_boolean
4
5
  false
5
6
  end
6
-
7
7
  end
8
-
@@ -1,29 +1,37 @@
1
+ # frozen_string_literal: true
2
+
1
3
  #------------------------------------------------------------------------------
2
4
  class Hash
3
-
4
- # takes a Hash (like the params hash), and converts the Rails date attributes
5
+ # takes a Hash (like the params hash), and converts the Rails date attributes
5
6
  # to a real Date object.
6
- # {'start_date(1i)' => 2012, 'start_date(2i)' => 11, 'start_date(3i)' => 23}.convert_date(:start_date)
7
+ # {'start_date(1i)' => 2012, 'start_date(2i)' => 11, 'start_date(3i)' => 23}.convert_date(:start_date)
7
8
  #------------------------------------------------------------------------------
8
9
  def convert_date(date_symbol_or_string)
9
10
  attribute = date_symbol_or_string.to_s
10
- return nil if self[attribute + '(1i)'].nil? || self[attribute + '(2i)'].nil? || self[attribute + '(3i)'].nil?
11
- return Date.new(self[attribute + '(1i)'].to_i, self[attribute + '(2i)'].to_i, self[attribute + '(3i)'].to_i)
11
+ return nil if self["#{attribute}(1i)"].nil? || self["#{attribute}(2i)"].nil? || self["#{attribute}(3i)"].nil?
12
+
13
+ Date.new(self["#{attribute}(1i)"].to_i, self["#{attribute}(2i)"].to_i, self["#{attribute}(3i)"].to_i)
12
14
  end
13
15
 
14
- # takes a Hash (like the params hash), and converts the Rails datetime attributes
16
+ # takes a Hash (like the params hash), and converts the Rails datetime attributes
15
17
  # to a real Date object.
16
18
  #------------------------------------------------------------------------------
17
19
  def convert_datetime(date_symbol_or_string)
18
20
  attribute = date_symbol_or_string.to_s
19
- return nil if self[attribute + '(1i)'].nil? || self[attribute + '(2i)'].nil? || self[attribute + '(3i)'].nil? || self[attribute + '(4i)'].nil? || self[attribute + '(5i)'].nil?
20
- return Time.local(self[attribute + '(1i)'].to_i, self[attribute + '(2i)'].to_i, self[attribute + '(3i)'].to_i, self[attribute + '(4i)'].to_i, self[attribute + '(5i)'].to_i)
21
+ if self["#{attribute}(1i)"].nil? || self["#{attribute}(2i)"].nil? ||
22
+ self["#{attribute}(3i)"].nil? || self["#{attribute}(4i)"].nil? ||
23
+ self["#{attribute}(5i)"].nil?
24
+ return nil
25
+ end
26
+
27
+ Time.local(self["#{attribute}(1i)"].to_i, self["#{attribute}(2i)"].to_i, self["#{attribute}(3i)"].to_i,
28
+ self["#{attribute}(4i)"].to_i, self["#{attribute}(5i)"].to_i)
21
29
  end
22
30
 
23
31
  # Convert hash of parameters to a query string
24
32
  #------------------------------------------------------------------------------
25
- def url_query_string(leading_slash = true)
26
- (leading_slash ? "/?" : "?") << URI.escape(self.collect{|k,v| "#{k}=#{v}"}.join('&'))
33
+ def url_query_string(leading_slash = true) # rubocop:disable Style/OptionalBooleanParameter
34
+ "#{leading_slash ? '/?' : '?'}#{to_query}"
27
35
  end
28
36
 
29
37
  # Borrowed from https://github.com/rubyworks/facets
@@ -42,7 +50,7 @@ class Hash
42
50
  # foo.rekey(:b=>:x) #=> { :a =>1, :x=>2 }
43
51
  # foo.rekey('foo'=>'bar') #=> { :a =>1, :b=>2 }
44
52
  #
45
- # If a block is given, converts all keys in the Hash accroding to the
53
+ # If a block is given, converts all keys in the Hash according to the
46
54
  # given block procedure.
47
55
  #
48
56
  # foo = { :name=>'Gavin', :wife=>:Lisa }
@@ -55,37 +63,36 @@ class Hash
55
63
  # Raises an ArgumentError if both a +key_map+ and a block are given.
56
64
  # If both are needed just call #rekey twice.
57
65
  #
58
- # TODO: If `nil` is returned by block should the key be set to `nil` or the orignal key?
66
+ # TODO: If `nil` is returned by block should the key be set to `nil` or the original key?
59
67
  #
60
68
  # CREDIT: Trans, Gavin Kistner
69
+ def rekey(key_map = nil, &block)
70
+ raise ArgumentError, 'argument or block' if key_map && block
61
71
 
62
- def rekey(key_map=nil, &block)
63
- raise ArgumentError, "argument or block" if key_map && block
64
-
65
- if !(key_map or block)
66
- block = lambda{|k| k.to_sym}
72
+ unless key_map || block
73
+ block = lambda { |k| k.to_sym } # rubocop:disable Style/SymbolProc, Style/Lambda
67
74
  end
68
75
 
69
76
  if block
70
77
  hash = dup.clear
71
78
  if block.arity.abs == 1
72
79
  each_pair do |k, v|
73
- hash[block[k]] = v #hash[block[k] || k] = v
80
+ hash[block[k]] = v # hash[block[k] || k] = v
74
81
  end
75
82
  else
76
83
  each_pair do |k, v|
77
- hash[block[k,v]] = v #hash[block[k,v] || k] = v
84
+ hash[block[k, v]] = v # hash[block[k,v] || k] = v
78
85
  end
79
86
  end
80
87
  else
81
- #hash = dup.clear # to keep default_proc
82
- #(keys - key_map.keys).each do |key|
83
- # hash[key] = self[key]
84
- #end
85
- #key_map.each do |from, to|
86
- # hash[to] = self[from] if key?(from)
87
- #end
88
- hash = dup # to keep default_proc
88
+ # hash = dup.clear # to keep default_proc
89
+ # (keys - key_map.keys).each do |key|
90
+ # hash[key] = self[key]
91
+ # end
92
+ # key_map.each do |from, to|
93
+ # hash[to] = self[from] if key?(from)
94
+ # end
95
+ hash = dup # to keep default_proc
89
96
  key_map.each_pair do |from, to|
90
97
  hash[to] = hash.delete(from) if hash.key?(from)
91
98
  end
@@ -102,8 +109,7 @@ class Hash
102
109
  #
103
110
  # CREDIT: Trans, Gavin Kistner
104
111
 
105
- def rekey!(key_map=nil, &block)
106
- replace(rekey(key_map, &block))
112
+ def rekey!(key_map = nil, &)
113
+ replace(rekey(key_map, &))
107
114
  end
108
-
109
115
  end
@@ -1,16 +1,17 @@
1
- class Integer
1
+ # frozen_string_literal: true
2
2
 
3
+ class Integer
3
4
  # Factorial of number
4
5
  # 5.factorial == 5 x 4 x 3 x 2 x 1 == 120
5
6
  #------------------------------------------------------------------------------
6
7
  def factorial
7
- return 1 if self.zero?
8
+ return 1 if zero?
9
+
8
10
  (1..self).inject(:*)
9
11
  end
10
12
 
11
13
  #------------------------------------------------------------------------------
12
14
  def as_boolean
13
- (self > 0) ? true : false
15
+ positive?
14
16
  end
15
-
16
17
  end
@@ -1,7 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # If nil, then return a default string
2
4
  #------------------------------------------------------------------------------
3
- class NilClass #:nodoc:
4
-
5
+ class NilClass # :nodoc:
5
6
  #------------------------------------------------------------------------------
6
7
  def to_s_default(default_str = 'n/a')
7
8
  default_str
@@ -11,7 +12,7 @@ class NilClass #:nodoc:
11
12
  def as_boolean
12
13
  false
13
14
  end
14
-
15
+
15
16
  #------------------------------------------------------------------------------
16
17
  def to_age
17
18
  0
@@ -19,18 +20,17 @@ class NilClass #:nodoc:
19
20
 
20
21
  #------------------------------------------------------------------------------
21
22
  def sql_wildcard
22
- "%"
23
+ '%'
23
24
  end
24
-
25
+
25
26
  #------------------------------------------------------------------------------
26
27
  def utc
27
- ""
28
+ ''
28
29
  end
29
-
30
+
30
31
  # if nil + something, just return something
31
32
  #------------------------------------------------------------------------------
32
- def +(y)
33
- y
33
+ def +(other)
34
+ other
34
35
  end
35
-
36
- end
36
+ end
@@ -1,6 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Numeric
2
4
  #------------------------------------------------------------------------------
3
- def percent_of(n, precision = 0)
4
- n == 0 ? 0 : (self.to_f / n.to_f * 100.0).round(precision)
5
+ def percent_of(num, precision = 0)
6
+ num.zero? ? 0 : (to_f / num * 100.0).round(precision)
5
7
  end
6
8
  end