activesupport-refinements 0.0.1

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.
Files changed (120) hide show
  1. data/.gitignore +17 -0
  2. data/Gemfile +6 -0
  3. data/LICENSE.txt +22 -0
  4. data/README.md +32 -0
  5. data/Rakefile +1 -0
  6. data/activesupport-refinements.gemspec +21 -0
  7. data/lib/active_support/refinements/core_ext/array.rb +7 -0
  8. data/lib/active_support/refinements/core_ext/array/access.rb +56 -0
  9. data/lib/active_support/refinements/core_ext/array/conversions.rb +224 -0
  10. data/lib/active_support/refinements/core_ext/array/extract_options.rb +31 -0
  11. data/lib/active_support/refinements/core_ext/array/grouping.rb +101 -0
  12. data/lib/active_support/refinements/core_ext/array/prepend_and_append.rb +9 -0
  13. data/lib/active_support/refinements/core_ext/array/uniq_by.rb +21 -0
  14. data/lib/active_support/refinements/core_ext/array/wrap.rb +48 -0
  15. data/lib/active_support/refinements/core_ext/benchmark.rb +7 -0
  16. data/lib/active_support/refinements/core_ext/big_decimal.rb +1 -0
  17. data/lib/active_support/refinements/core_ext/big_decimal/conversions.rb +32 -0
  18. data/lib/active_support/refinements/core_ext/class.rb +4 -0
  19. data/lib/active_support/refinements/core_ext/class/attribute.rb +119 -0
  20. data/lib/active_support/refinements/core_ext/class/attribute_accessors.rb +172 -0
  21. data/lib/active_support/refinements/core_ext/class/delegating_attributes.rb +42 -0
  22. data/lib/active_support/refinements/core_ext/class/subclasses.rb +44 -0
  23. data/lib/active_support/refinements/core_ext/date.rb +5 -0
  24. data/lib/active_support/refinements/core_ext/date/acts_like.rb +10 -0
  25. data/lib/active_support/refinements/core_ext/date/calculations.rb +123 -0
  26. data/lib/active_support/refinements/core_ext/date/conversions.rb +86 -0
  27. data/lib/active_support/refinements/core_ext/date/zones.rb +17 -0
  28. data/lib/active_support/refinements/core_ext/date_and_time/calculations.rb +232 -0
  29. data/lib/active_support/refinements/core_ext/date_time.rb +4 -0
  30. data/lib/active_support/refinements/core_ext/date_time/acts_like.rb +15 -0
  31. data/lib/active_support/refinements/core_ext/date_time/calculations.rb +143 -0
  32. data/lib/active_support/refinements/core_ext/date_time/conversions.rb +93 -0
  33. data/lib/active_support/refinements/core_ext/date_time/zones.rb +26 -0
  34. data/lib/active_support/refinements/core_ext/enumerable.rb +82 -0
  35. data/lib/active_support/refinements/core_ext/exception.rb +5 -0
  36. data/lib/active_support/refinements/core_ext/file.rb +1 -0
  37. data/lib/active_support/refinements/core_ext/file/atomic.rb +60 -0
  38. data/lib/active_support/refinements/core_ext/hash.rb +8 -0
  39. data/lib/active_support/refinements/core_ext/hash/conversions.rb +161 -0
  40. data/lib/active_support/refinements/core_ext/hash/deep_merge.rb +29 -0
  41. data/lib/active_support/refinements/core_ext/hash/diff.rb +15 -0
  42. data/lib/active_support/refinements/core_ext/hash/except.rb +17 -0
  43. data/lib/active_support/refinements/core_ext/hash/indifferent_access.rb +24 -0
  44. data/lib/active_support/refinements/core_ext/hash/keys.rb +140 -0
  45. data/lib/active_support/refinements/core_ext/hash/reverse_merge.rb +24 -0
  46. data/lib/active_support/refinements/core_ext/hash/slice.rb +42 -0
  47. data/lib/active_support/refinements/core_ext/integer.rb +3 -0
  48. data/lib/active_support/refinements/core_ext/integer/inflections.rb +31 -0
  49. data/lib/active_support/refinements/core_ext/integer/multiple.rb +12 -0
  50. data/lib/active_support/refinements/core_ext/integer/time.rb +43 -0
  51. data/lib/active_support/refinements/core_ext/kernel.rb +4 -0
  52. data/lib/active_support/refinements/core_ext/kernel/agnostics.rb +13 -0
  53. data/lib/active_support/refinements/core_ext/kernel/debugger.rb +12 -0
  54. data/lib/active_support/refinements/core_ext/kernel/reporting.rb +97 -0
  55. data/lib/active_support/refinements/core_ext/kernel/singleton_class.rb +8 -0
  56. data/lib/active_support/refinements/core_ext/load_error.rb +27 -0
  57. data/lib/active_support/refinements/core_ext/logger.rb +86 -0
  58. data/lib/active_support/refinements/core_ext/module.rb +10 -0
  59. data/lib/active_support/refinements/core_ext/module/aliasing.rb +69 -0
  60. data/lib/active_support/refinements/core_ext/module/anonymous.rb +21 -0
  61. data/lib/active_support/refinements/core_ext/module/attr_internal.rb +40 -0
  62. data/lib/active_support/refinements/core_ext/module/attribute_accessors.rb +68 -0
  63. data/lib/active_support/refinements/core_ext/module/delegation.rb +172 -0
  64. data/lib/active_support/refinements/core_ext/module/deprecation.rb +27 -0
  65. data/lib/active_support/refinements/core_ext/module/introspection.rb +80 -0
  66. data/lib/active_support/refinements/core_ext/module/qualified_const.rb +54 -0
  67. data/lib/active_support/refinements/core_ext/module/reachable.rb +10 -0
  68. data/lib/active_support/refinements/core_ext/module/remove_method.rb +14 -0
  69. data/lib/active_support/refinements/core_ext/name_error.rb +20 -0
  70. data/lib/active_support/refinements/core_ext/numeric.rb +3 -0
  71. data/lib/active_support/refinements/core_ext/numeric/bytes.rb +46 -0
  72. data/lib/active_support/refinements/core_ext/numeric/conversions.rb +137 -0
  73. data/lib/active_support/refinements/core_ext/numeric/time.rb +81 -0
  74. data/lib/active_support/refinements/core_ext/object.rb +14 -0
  75. data/lib/active_support/refinements/core_ext/object/acts_like.rb +12 -0
  76. data/lib/active_support/refinements/core_ext/object/blank.rb +107 -0
  77. data/lib/active_support/refinements/core_ext/object/conversions.rb +4 -0
  78. data/lib/active_support/refinements/core_ext/object/deep_dup.rb +48 -0
  79. data/lib/active_support/refinements/core_ext/object/duplicable.rb +92 -0
  80. data/lib/active_support/refinements/core_ext/object/inclusion.rb +27 -0
  81. data/lib/active_support/refinements/core_ext/object/instance_variables.rb +30 -0
  82. data/lib/active_support/refinements/core_ext/object/to_json.rb +27 -0
  83. data/lib/active_support/refinements/core_ext/object/to_param.rb +60 -0
  84. data/lib/active_support/refinements/core_ext/object/to_query.rb +29 -0
  85. data/lib/active_support/refinements/core_ext/object/try.rb +72 -0
  86. data/lib/active_support/refinements/core_ext/object/with_options.rb +44 -0
  87. data/lib/active_support/refinements/core_ext/proc.rb +19 -0
  88. data/lib/active_support/refinements/core_ext/range.rb +3 -0
  89. data/lib/active_support/refinements/core_ext/range/conversions.rb +21 -0
  90. data/lib/active_support/refinements/core_ext/range/include_range.rb +23 -0
  91. data/lib/active_support/refinements/core_ext/range/overlaps.rb +10 -0
  92. data/lib/active_support/refinements/core_ext/regexp.rb +7 -0
  93. data/lib/active_support/refinements/core_ext/string.rb +13 -0
  94. data/lib/active_support/refinements/core_ext/string/access.rb +106 -0
  95. data/lib/active_support/refinements/core_ext/string/behavior.rb +8 -0
  96. data/lib/active_support/refinements/core_ext/string/conversions.rb +60 -0
  97. data/lib/active_support/refinements/core_ext/string/encoding.rb +10 -0
  98. data/lib/active_support/refinements/core_ext/string/exclude.rb +13 -0
  99. data/lib/active_support/refinements/core_ext/string/filters.rb +54 -0
  100. data/lib/active_support/refinements/core_ext/string/indent.rb +45 -0
  101. data/lib/active_support/refinements/core_ext/string/inflections.rb +214 -0
  102. data/lib/active_support/refinements/core_ext/string/inquiry.rb +15 -0
  103. data/lib/active_support/refinements/core_ext/string/multibyte.rb +58 -0
  104. data/lib/active_support/refinements/core_ext/string/output_safety.rb +194 -0
  105. data/lib/active_support/refinements/core_ext/string/starts_ends_with.rb +6 -0
  106. data/lib/active_support/refinements/core_ext/string/strip.rb +28 -0
  107. data/lib/active_support/refinements/core_ext/string/xchar.rb +18 -0
  108. data/lib/active_support/refinements/core_ext/time.rb +5 -0
  109. data/lib/active_support/refinements/core_ext/time/acts_like.rb +10 -0
  110. data/lib/active_support/refinements/core_ext/time/calculations.rb +251 -0
  111. data/lib/active_support/refinements/core_ext/time/conversions.rb +65 -0
  112. data/lib/active_support/refinements/core_ext/time/marshal.rb +30 -0
  113. data/lib/active_support/refinements/core_ext/time/zones.rb +98 -0
  114. data/lib/active_support/refinements/core_ext/uri.rb +28 -0
  115. data/lib/activesupport-refinements.rb +9 -0
  116. data/lib/activesupport-refinements/version.rb +5 -0
  117. data/refine_core_ext.rb +45 -0
  118. data/spec/hwia_spec.rb +15 -0
  119. data/spec/try_spec.rb +18 -0
  120. metadata +182 -0
@@ -0,0 +1,14 @@
1
+ module ModuleExt; end; module ModuleExt::RemoveMethod
2
+ refine Module do
3
+ def remove_possible_method(method)
4
+ if method_defined?(method) || private_method_defined?(method)
5
+ undef_method(method)
6
+ end
7
+ end
8
+
9
+ def redefine_method(method, &block)
10
+ remove_possible_method(method)
11
+ define_method(method, &block)
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,20 @@
1
+ module NameErrorExt
2
+ refine NameError do
3
+ # Extract the name of the missing constant from the exception message.
4
+ def missing_name
5
+ if /undefined local variable or method/ !~ message
6
+ $1 if /((::)?([A-Z]\w*)(::[A-Z]\w*)*)$/ =~ message
7
+ end
8
+ end
9
+
10
+ # Was this exception raised because the given name was missing?
11
+ def missing_name?(name)
12
+ if name.is_a? Symbol
13
+ last_name = (missing_name || '').split('::').last
14
+ last_name == name.to_s
15
+ else
16
+ missing_name == name.to_s
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,3 @@
1
+ require 'active_support/refinements/core_ext/numeric/bytes'
2
+ require 'active_support/refinements/core_ext/numeric/time'
3
+ require 'active_support/refinements/core_ext/numeric/conversions'
@@ -0,0 +1,46 @@
1
+ module NumericExt; end; module NumericExt::Bytes
2
+ refine Numeric do
3
+ KILOBYTE = 1024
4
+ MEGABYTE = KILOBYTE * 1024
5
+ GIGABYTE = MEGABYTE * 1024
6
+ TERABYTE = GIGABYTE * 1024
7
+ PETABYTE = TERABYTE * 1024
8
+ EXABYTE = PETABYTE * 1024
9
+
10
+ # Enables the use of byte calculations and declarations, like 45.bytes + 2.6.megabytes
11
+ def bytes
12
+ self
13
+ end
14
+ # alias :byte :bytes
15
+
16
+ def kilobytes
17
+ self * KILOBYTE
18
+ end
19
+ # alias :kilobyte :kilobytes
20
+
21
+ def megabytes
22
+ self * MEGABYTE
23
+ end
24
+ # alias :megabyte :megabytes
25
+
26
+ def gigabytes
27
+ self * GIGABYTE
28
+ end
29
+ # alias :gigabyte :gigabytes
30
+
31
+ def terabytes
32
+ self * TERABYTE
33
+ end
34
+ # alias :terabyte :terabytes
35
+
36
+ def petabytes
37
+ self * PETABYTE
38
+ end
39
+ # alias :petabyte :petabytes
40
+
41
+ def exabytes
42
+ self * EXABYTE
43
+ end
44
+ # alias :exabyte :exabytes
45
+ end
46
+ end
@@ -0,0 +1,137 @@
1
+ module NumericExt; end; module NumericExt::Conversions
2
+ require 'active_support/refinements/core_ext/big_decimal/conversions'
3
+ require 'active_support/number_helper'
4
+
5
+ refine Numeric do
6
+
7
+ # Provides options for converting numbers into formatted strings.
8
+ # Options are provided for phone numbers, currency, percentage,
9
+ # precision, positional notation, file size and pretty printing.
10
+ #
11
+ # ==== Options
12
+ #
13
+ # For details on which formats use which options, see ActiveSupport::NumberHelper
14
+ #
15
+ # ==== Examples
16
+ #
17
+ # Phone Numbers:
18
+ # 5551234.to_s(:phone) # => 555-1234
19
+ # 1235551234.to_s(:phone) # => 123-555-1234
20
+ # 1235551234.to_s(:phone, area_code: true) # => (123) 555-1234
21
+ # 1235551234.to_s(:phone, delimiter: ' ') # => 123 555 1234
22
+ # 1235551234.to_s(:phone, area_code: true, extension: 555) # => (123) 555-1234 x 555
23
+ # 1235551234.to_s(:phone, country_code: 1) # => +1-123-555-1234
24
+ # 1235551234.to_s(:phone, country_code: 1, extension: 1343, delimiter: '.')
25
+ # # => +1.123.555.1234 x 1343
26
+ #
27
+ # Currency:
28
+ # 1234567890.50.to_s(:currency) # => $1,234,567,890.50
29
+ # 1234567890.506.to_s(:currency) # => $1,234,567,890.51
30
+ # 1234567890.506.to_s(:currency, precision: 3) # => $1,234,567,890.506
31
+ # 1234567890.506.to_s(:currency, locale: :fr) # => 1 234 567 890,51 €
32
+ # -1234567890.50.to_s(:currency, negative_format: '(%u%n)')
33
+ # # => ($1,234,567,890.50)
34
+ # 1234567890.50.to_s(:currency, unit: '£', separator: ',', delimiter: '')
35
+ # # => £1234567890,50
36
+ # 1234567890.50.to_s(:currency, unit: '£', separator: ',', delimiter: '', format: '%n %u')
37
+ # # => 1234567890,50 £
38
+ #
39
+ # Percentage:
40
+ # 100.to_s(:percentage) # => 100.000%
41
+ # 100.to_s(:percentage, precision: 0) # => 100%
42
+ # 1000.to_s(:percentage, delimiter: '.', separator: ',') # => 1.000,000%
43
+ # 302.24398923423.to_s(:percentage, precision: 5) # => 302.24399%
44
+ # 1000.to_s(:percentage, locale: :fr) # => 1 000,000%
45
+ # 100.to_s(:percentage, format: '%n %') # => 100 %
46
+ #
47
+ # Delimited:
48
+ # 12345678.to_s(:delimited) # => 12,345,678
49
+ # 12345678.05.to_s(:delimited) # => 12,345,678.05
50
+ # 12345678.to_s(:delimited, delimiter: '.') # => 12.345.678
51
+ # 12345678.to_s(:delimited, delimiter: ',') # => 12,345,678
52
+ # 12345678.05.to_s(:delimited, separator: ' ') # => 12,345,678 05
53
+ # 12345678.05.to_s(:delimited, locale: :fr) # => 12 345 678,05
54
+ # 98765432.98.to_s(:delimited, delimiter: ' ', separator: ',')
55
+ # # => 98 765 432,98
56
+ #
57
+ # Rounded:
58
+ # 111.2345.to_s(:rounded) # => 111.235
59
+ # 111.2345.to_s(:rounded, precision: 2) # => 111.23
60
+ # 13.to_s(:rounded, precision: 5) # => 13.00000
61
+ # 389.32314.to_s(:rounded, precision: 0) # => 389
62
+ # 111.2345.to_s(:rounded, significant: true) # => 111
63
+ # 111.2345.to_s(:rounded, precision: 1, significant: true) # => 100
64
+ # 13.to_s(:rounded, precision: 5, significant: true) # => 13.000
65
+ # 111.234.to_s(:rounded, locale: :fr) # => 111,234
66
+ # 13.to_s(:rounded, precision: 5, significant: true, strip_insignificant_zeros: true)
67
+ # # => 13
68
+ # 389.32314.to_s(:rounded, precision: 4, significant: true) # => 389.3
69
+ # 1111.2345.to_s(:rounded, precision: 2, separator: ',', delimiter: '.')
70
+ # # => 1.111,23
71
+ #
72
+ # Human-friendly size in Bytes:
73
+ # 123.to_s(:human_size) # => 123 Bytes
74
+ # 1234.to_s(:human_size) # => 1.21 KB
75
+ # 12345.to_s(:human_size) # => 12.1 KB
76
+ # 1234567.to_s(:human_size) # => 1.18 MB
77
+ # 1234567890.to_s(:human_size) # => 1.15 GB
78
+ # 1234567890123.to_s(:human_size) # => 1.12 TB
79
+ # 1234567.to_s(:human_size, precision: 2) # => 1.2 MB
80
+ # 483989.to_s(:human_size, precision: 2) # => 470 KB
81
+ # 1234567.to_s(:human_size, precision: 2, separator: ',') # => 1,2 MB
82
+ # 1234567890123.to_s(:human_size, precision: 5) # => "1.1229 TB"
83
+ # 524288000.to_s(:human_size, precision: 5) # => "500 MB"
84
+ #
85
+ # Human-friendly format:
86
+ # 123.to_s(:human) # => "123"
87
+ # 1234.to_s(:human) # => "1.23 Thousand"
88
+ # 12345.to_s(:human) # => "12.3 Thousand"
89
+ # 1234567.to_s(:human) # => "1.23 Million"
90
+ # 1234567890.to_s(:human) # => "1.23 Billion"
91
+ # 1234567890123.to_s(:human) # => "1.23 Trillion"
92
+ # 1234567890123456.to_s(:human) # => "1.23 Quadrillion"
93
+ # 1234567890123456789.to_s(:human) # => "1230 Quadrillion"
94
+ # 489939.to_s(:human, precision: 2) # => "490 Thousand"
95
+ # 489939.to_s(:human, precision: 4) # => "489.9 Thousand"
96
+ # 1234567.to_s(:human, precision: 4,
97
+ # significant: false) # => "1.2346 Million"
98
+ # 1234567.to_s(:human, precision: 1,
99
+ # separator: ',',
100
+ # significant: false) # => "1,2 Million"
101
+ def to_formatted_s(format = :default, options = {})
102
+ case format
103
+ when :phone
104
+ return ActiveSupport::NumberHelper.number_to_phone(self, options)
105
+ when :currency
106
+ return ActiveSupport::NumberHelper.number_to_currency(self, options)
107
+ when :percentage
108
+ return ActiveSupport::NumberHelper.number_to_percentage(self, options)
109
+ when :delimited
110
+ return ActiveSupport::NumberHelper.number_to_delimited(self, options)
111
+ when :rounded
112
+ return ActiveSupport::NumberHelper.number_to_rounded(self, options)
113
+ when :human
114
+ return ActiveSupport::NumberHelper.number_to_human(self, options)
115
+ when :human_size
116
+ return ActiveSupport::NumberHelper.number_to_human_size(self, options)
117
+ else
118
+ self.to_default_s
119
+ end
120
+ end
121
+
122
+ [Float, Fixnum, Bignum, BigDecimal].each do |klass|
123
+ klass.send(:alias_method, :to_default_s, :to_s)
124
+
125
+ klass.send(:define_method, :to_s) do |*args|
126
+ if args[0].is_a?(Symbol)
127
+ format = args[0]
128
+ options = args[1] || {}
129
+
130
+ self.to_formatted_s(format, options)
131
+ else
132
+ to_default_s(*args)
133
+ end
134
+ end
135
+ end
136
+ end
137
+ end
@@ -0,0 +1,81 @@
1
+ module NumericExt; end; module NumericExt::Time
2
+ require 'active_support/duration'
3
+ require 'active_support/refinements/core_ext/time/calculations'
4
+ require 'active_support/refinements/core_ext/time/acts_like'
5
+
6
+ refine Numeric do
7
+ # Enables the use of time calculations and declarations, like 45.minutes + 2.hours + 4.years.
8
+ #
9
+ # These methods use Time#advance for precise date calculations when using from_now, ago, etc.
10
+ # as well as adding or subtracting their results from a Time object. For example:
11
+ #
12
+ # # equivalent to Time.current.advance(months: 1)
13
+ # 1.month.from_now
14
+ #
15
+ # # equivalent to Time.current.advance(years: 2)
16
+ # 2.years.from_now
17
+ #
18
+ # # equivalent to Time.current.advance(months: 4, years: 5)
19
+ # (4.months + 5.years).from_now
20
+ #
21
+ # While these methods provide precise calculation when used as in the examples above, care
22
+ # should be taken to note that this is not true if the result of `months', `years', etc is
23
+ # converted before use:
24
+ #
25
+ # # equivalent to 30.days.to_i.from_now
26
+ # 1.month.to_i.from_now
27
+ #
28
+ # # equivalent to 365.25.days.to_f.from_now
29
+ # 1.year.to_f.from_now
30
+ #
31
+ # In such cases, Ruby's core
32
+ # Date[http://ruby-doc.org/stdlib/libdoc/date/rdoc/Date.html] and
33
+ # Time[http://ruby-doc.org/stdlib/libdoc/time/rdoc/Time.html] should be used for precision
34
+ # date and time arithmetic.
35
+ def seconds
36
+ ActiveSupport::Duration.new(self, [[:seconds, self]])
37
+ end
38
+ # alias :second :seconds
39
+
40
+ def minutes
41
+ ActiveSupport::Duration.new(self * 60, [[:seconds, self * 60]])
42
+ end
43
+ # alias :minute :minutes
44
+
45
+ def hours
46
+ ActiveSupport::Duration.new(self * 3600, [[:seconds, self * 3600]])
47
+ end
48
+ # alias :hour :hours
49
+
50
+ def days
51
+ ActiveSupport::Duration.new(self * 24.hours, [[:days, self]])
52
+ end
53
+ # alias :day :days
54
+
55
+ def weeks
56
+ ActiveSupport::Duration.new(self * 7.days, [[:days, self * 7]])
57
+ end
58
+ # alias :week :weeks
59
+
60
+ def fortnights
61
+ ActiveSupport::Duration.new(self * 2.weeks, [[:days, self * 14]])
62
+ end
63
+ # alias :fortnight :fortnights
64
+
65
+ # Reads best without arguments: 10.minutes.ago
66
+ def ago(time = ::Time.current)
67
+ time - self
68
+ end
69
+
70
+ # Reads best with argument: 10.minutes.until(time)
71
+ # alias :until :ago
72
+
73
+ # Reads best with argument: 10.minutes.since(time)
74
+ def since(time = ::Time.current)
75
+ time + self
76
+ end
77
+
78
+ # Reads best without arguments: 10.minutes.from_now
79
+ # alias :from_now :since
80
+ end
81
+ end
@@ -0,0 +1,14 @@
1
+ require 'active_support/refinements/core_ext/object/acts_like'
2
+ require 'active_support/refinements/core_ext/object/blank'
3
+ require 'active_support/refinements/core_ext/object/duplicable'
4
+ require 'active_support/refinements/core_ext/object/deep_dup'
5
+ require 'active_support/refinements/core_ext/object/try'
6
+ require 'active_support/refinements/core_ext/object/inclusion'
7
+
8
+ require 'active_support/refinements/core_ext/object/conversions'
9
+ require 'active_support/refinements/core_ext/object/instance_variables'
10
+
11
+ require 'active_support/refinements/core_ext/object/to_json'
12
+ require 'active_support/refinements/core_ext/object/to_param'
13
+ require 'active_support/refinements/core_ext/object/to_query'
14
+ require 'active_support/refinements/core_ext/object/with_options'
@@ -0,0 +1,12 @@
1
+ module ObjectExt; end; module ObjectExt::ActsLike
2
+ refine Object do
3
+ # A duck-type assistant method. For example, Active Support extends Date
4
+ # to define an acts_like_date? method, and extends Time to define
5
+ # acts_like_time?. As a result, we can do "x.acts_like?(:time)" and
6
+ # "x.acts_like?(:date)" to do duck-type-safe comparisons, since classes that
7
+ # we want to act like Time simply need to define an acts_like_time? method.
8
+ def acts_like?(duck)
9
+ respond_to? :"acts_like_#{duck}?"
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,107 @@
1
+ module ObjectExt; end; module ObjectExt::Blank
2
+ # encoding: utf-8
3
+
4
+ refine Object do
5
+ # An object is blank if it's false, empty, or a whitespace string.
6
+ # For example, '', ' ', +nil+, [], and {} are all blank.
7
+ #
8
+ # This simplifies:
9
+ #
10
+ # if address.nil? || address.empty?
11
+ #
12
+ # ...to:
13
+ #
14
+ # if address.blank?
15
+ def blank?
16
+ respond_to?(:empty?) ? empty? : !self
17
+ end
18
+
19
+ # An object is present if it's not <tt>blank?</tt>.
20
+ def present?
21
+ !blank?
22
+ end
23
+
24
+ # Returns object if it's <tt>present?</tt> otherwise returns +nil+.
25
+ # <tt>object.presence</tt> is equivalent to <tt>object.present? ? object : nil</tt>.
26
+ #
27
+ # This is handy for any representation of objects where blank is the same
28
+ # as not present at all. For example, this simplifies a common check for
29
+ # HTTP POST/query parameters:
30
+ #
31
+ # state = params[:state] if params[:state].present?
32
+ # country = params[:country] if params[:country].present?
33
+ # region = state || country || 'US'
34
+ #
35
+ # ...becomes:
36
+ #
37
+ # region = params[:state].presence || params[:country].presence || 'US'
38
+ def presence
39
+ self if present?
40
+ end
41
+ end
42
+
43
+ refine NilClass do
44
+ # +nil+ is blank:
45
+ #
46
+ # nil.blank? # => true
47
+ def blank?
48
+ true
49
+ end
50
+ end
51
+
52
+ refine FalseClass do
53
+ # +false+ is blank:
54
+ #
55
+ # false.blank? # => true
56
+ def blank?
57
+ true
58
+ end
59
+ end
60
+
61
+ refine TrueClass do
62
+ # +true+ is not blank:
63
+ #
64
+ # true.blank? # => false
65
+ def blank?
66
+ false
67
+ end
68
+ end
69
+
70
+ refine Array do
71
+ # An array is blank if it's empty:
72
+ #
73
+ # [].blank? # => true
74
+ # [1,2,3].blank? # => false
75
+ # alias_method :blank?, :empty?
76
+ end
77
+
78
+ refine Hash do
79
+ # A hash is blank if it's empty:
80
+ #
81
+ # {}.blank? # => true
82
+ # { key: 'value' }.blank? # => false
83
+ # alias_method :blank?, :empty?
84
+ end
85
+
86
+ refine String do
87
+ # A string is blank if it's empty or contains whitespaces only:
88
+ #
89
+ # ''.blank? # => true
90
+ # ' '.blank? # => true
91
+ # ' '.blank? # => true
92
+ # ' something here '.blank? # => false
93
+ def blank?
94
+ self !~ /[^[:space:]]/
95
+ end
96
+ end
97
+
98
+ refine Numeric do
99
+ # No number is blank:
100
+ #
101
+ # 1.blank? # => false
102
+ # 0.blank? # => false
103
+ def blank?
104
+ false
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,4 @@
1
+ require 'active_support/refinements/core_ext/object/to_param'
2
+ require 'active_support/refinements/core_ext/object/to_query'
3
+ require 'active_support/refinements/core_ext/array/conversions'
4
+ require 'active_support/refinements/core_ext/hash/conversions'