activesupport-refinements 0.0.1

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