activesupport-refinements 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +17 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +22 -0
- data/README.md +32 -0
- data/Rakefile +1 -0
- data/activesupport-refinements.gemspec +21 -0
- data/lib/active_support/refinements/core_ext/array.rb +7 -0
- data/lib/active_support/refinements/core_ext/array/access.rb +56 -0
- data/lib/active_support/refinements/core_ext/array/conversions.rb +224 -0
- data/lib/active_support/refinements/core_ext/array/extract_options.rb +31 -0
- data/lib/active_support/refinements/core_ext/array/grouping.rb +101 -0
- data/lib/active_support/refinements/core_ext/array/prepend_and_append.rb +9 -0
- data/lib/active_support/refinements/core_ext/array/uniq_by.rb +21 -0
- data/lib/active_support/refinements/core_ext/array/wrap.rb +48 -0
- data/lib/active_support/refinements/core_ext/benchmark.rb +7 -0
- data/lib/active_support/refinements/core_ext/big_decimal.rb +1 -0
- data/lib/active_support/refinements/core_ext/big_decimal/conversions.rb +32 -0
- data/lib/active_support/refinements/core_ext/class.rb +4 -0
- data/lib/active_support/refinements/core_ext/class/attribute.rb +119 -0
- data/lib/active_support/refinements/core_ext/class/attribute_accessors.rb +172 -0
- data/lib/active_support/refinements/core_ext/class/delegating_attributes.rb +42 -0
- data/lib/active_support/refinements/core_ext/class/subclasses.rb +44 -0
- data/lib/active_support/refinements/core_ext/date.rb +5 -0
- data/lib/active_support/refinements/core_ext/date/acts_like.rb +10 -0
- data/lib/active_support/refinements/core_ext/date/calculations.rb +123 -0
- data/lib/active_support/refinements/core_ext/date/conversions.rb +86 -0
- data/lib/active_support/refinements/core_ext/date/zones.rb +17 -0
- data/lib/active_support/refinements/core_ext/date_and_time/calculations.rb +232 -0
- data/lib/active_support/refinements/core_ext/date_time.rb +4 -0
- data/lib/active_support/refinements/core_ext/date_time/acts_like.rb +15 -0
- data/lib/active_support/refinements/core_ext/date_time/calculations.rb +143 -0
- data/lib/active_support/refinements/core_ext/date_time/conversions.rb +93 -0
- data/lib/active_support/refinements/core_ext/date_time/zones.rb +26 -0
- data/lib/active_support/refinements/core_ext/enumerable.rb +82 -0
- data/lib/active_support/refinements/core_ext/exception.rb +5 -0
- data/lib/active_support/refinements/core_ext/file.rb +1 -0
- data/lib/active_support/refinements/core_ext/file/atomic.rb +60 -0
- data/lib/active_support/refinements/core_ext/hash.rb +8 -0
- data/lib/active_support/refinements/core_ext/hash/conversions.rb +161 -0
- data/lib/active_support/refinements/core_ext/hash/deep_merge.rb +29 -0
- data/lib/active_support/refinements/core_ext/hash/diff.rb +15 -0
- data/lib/active_support/refinements/core_ext/hash/except.rb +17 -0
- data/lib/active_support/refinements/core_ext/hash/indifferent_access.rb +24 -0
- data/lib/active_support/refinements/core_ext/hash/keys.rb +140 -0
- data/lib/active_support/refinements/core_ext/hash/reverse_merge.rb +24 -0
- data/lib/active_support/refinements/core_ext/hash/slice.rb +42 -0
- data/lib/active_support/refinements/core_ext/integer.rb +3 -0
- data/lib/active_support/refinements/core_ext/integer/inflections.rb +31 -0
- data/lib/active_support/refinements/core_ext/integer/multiple.rb +12 -0
- data/lib/active_support/refinements/core_ext/integer/time.rb +43 -0
- data/lib/active_support/refinements/core_ext/kernel.rb +4 -0
- data/lib/active_support/refinements/core_ext/kernel/agnostics.rb +13 -0
- data/lib/active_support/refinements/core_ext/kernel/debugger.rb +12 -0
- data/lib/active_support/refinements/core_ext/kernel/reporting.rb +97 -0
- data/lib/active_support/refinements/core_ext/kernel/singleton_class.rb +8 -0
- data/lib/active_support/refinements/core_ext/load_error.rb +27 -0
- data/lib/active_support/refinements/core_ext/logger.rb +86 -0
- data/lib/active_support/refinements/core_ext/module.rb +10 -0
- data/lib/active_support/refinements/core_ext/module/aliasing.rb +69 -0
- data/lib/active_support/refinements/core_ext/module/anonymous.rb +21 -0
- data/lib/active_support/refinements/core_ext/module/attr_internal.rb +40 -0
- data/lib/active_support/refinements/core_ext/module/attribute_accessors.rb +68 -0
- data/lib/active_support/refinements/core_ext/module/delegation.rb +172 -0
- data/lib/active_support/refinements/core_ext/module/deprecation.rb +27 -0
- data/lib/active_support/refinements/core_ext/module/introspection.rb +80 -0
- data/lib/active_support/refinements/core_ext/module/qualified_const.rb +54 -0
- data/lib/active_support/refinements/core_ext/module/reachable.rb +10 -0
- data/lib/active_support/refinements/core_ext/module/remove_method.rb +14 -0
- data/lib/active_support/refinements/core_ext/name_error.rb +20 -0
- data/lib/active_support/refinements/core_ext/numeric.rb +3 -0
- data/lib/active_support/refinements/core_ext/numeric/bytes.rb +46 -0
- data/lib/active_support/refinements/core_ext/numeric/conversions.rb +137 -0
- data/lib/active_support/refinements/core_ext/numeric/time.rb +81 -0
- data/lib/active_support/refinements/core_ext/object.rb +14 -0
- data/lib/active_support/refinements/core_ext/object/acts_like.rb +12 -0
- data/lib/active_support/refinements/core_ext/object/blank.rb +107 -0
- data/lib/active_support/refinements/core_ext/object/conversions.rb +4 -0
- data/lib/active_support/refinements/core_ext/object/deep_dup.rb +48 -0
- data/lib/active_support/refinements/core_ext/object/duplicable.rb +92 -0
- data/lib/active_support/refinements/core_ext/object/inclusion.rb +27 -0
- data/lib/active_support/refinements/core_ext/object/instance_variables.rb +30 -0
- data/lib/active_support/refinements/core_ext/object/to_json.rb +27 -0
- data/lib/active_support/refinements/core_ext/object/to_param.rb +60 -0
- data/lib/active_support/refinements/core_ext/object/to_query.rb +29 -0
- data/lib/active_support/refinements/core_ext/object/try.rb +72 -0
- data/lib/active_support/refinements/core_ext/object/with_options.rb +44 -0
- data/lib/active_support/refinements/core_ext/proc.rb +19 -0
- data/lib/active_support/refinements/core_ext/range.rb +3 -0
- data/lib/active_support/refinements/core_ext/range/conversions.rb +21 -0
- data/lib/active_support/refinements/core_ext/range/include_range.rb +23 -0
- data/lib/active_support/refinements/core_ext/range/overlaps.rb +10 -0
- data/lib/active_support/refinements/core_ext/regexp.rb +7 -0
- data/lib/active_support/refinements/core_ext/string.rb +13 -0
- data/lib/active_support/refinements/core_ext/string/access.rb +106 -0
- data/lib/active_support/refinements/core_ext/string/behavior.rb +8 -0
- data/lib/active_support/refinements/core_ext/string/conversions.rb +60 -0
- data/lib/active_support/refinements/core_ext/string/encoding.rb +10 -0
- data/lib/active_support/refinements/core_ext/string/exclude.rb +13 -0
- data/lib/active_support/refinements/core_ext/string/filters.rb +54 -0
- data/lib/active_support/refinements/core_ext/string/indent.rb +45 -0
- data/lib/active_support/refinements/core_ext/string/inflections.rb +214 -0
- data/lib/active_support/refinements/core_ext/string/inquiry.rb +15 -0
- data/lib/active_support/refinements/core_ext/string/multibyte.rb +58 -0
- data/lib/active_support/refinements/core_ext/string/output_safety.rb +194 -0
- data/lib/active_support/refinements/core_ext/string/starts_ends_with.rb +6 -0
- data/lib/active_support/refinements/core_ext/string/strip.rb +28 -0
- data/lib/active_support/refinements/core_ext/string/xchar.rb +18 -0
- data/lib/active_support/refinements/core_ext/time.rb +5 -0
- data/lib/active_support/refinements/core_ext/time/acts_like.rb +10 -0
- data/lib/active_support/refinements/core_ext/time/calculations.rb +251 -0
- data/lib/active_support/refinements/core_ext/time/conversions.rb +65 -0
- data/lib/active_support/refinements/core_ext/time/marshal.rb +30 -0
- data/lib/active_support/refinements/core_ext/time/zones.rb +98 -0
- data/lib/active_support/refinements/core_ext/uri.rb +28 -0
- data/lib/activesupport-refinements.rb +9 -0
- data/lib/activesupport-refinements/version.rb +5 -0
- data/refine_core_ext.rb +45 -0
- data/spec/hwia_spec.rb +15 -0
- data/spec/try_spec.rb +18 -0
- metadata +182 -0
@@ -0,0 +1,31 @@
|
|
1
|
+
module IntegerExt; end; module IntegerExt::Inflections
|
2
|
+
require 'active_support/inflector'
|
3
|
+
|
4
|
+
refine Integer do
|
5
|
+
# Ordinalize turns a number into an ordinal string used to denote the
|
6
|
+
# position in an ordered sequence such as 1st, 2nd, 3rd, 4th.
|
7
|
+
#
|
8
|
+
# 1.ordinalize # => "1st"
|
9
|
+
# 2.ordinalize # => "2nd"
|
10
|
+
# 1002.ordinalize # => "1002nd"
|
11
|
+
# 1003.ordinalize # => "1003rd"
|
12
|
+
# -11.ordinalize # => "-11th"
|
13
|
+
# -1001.ordinalize # => "-1001st"
|
14
|
+
def ordinalize
|
15
|
+
ActiveSupport::Inflector.ordinalize(self)
|
16
|
+
end
|
17
|
+
|
18
|
+
# Ordinal returns the suffix used to denote the position
|
19
|
+
# in an ordered sequence such as 1st, 2nd, 3rd, 4th.
|
20
|
+
#
|
21
|
+
# 1.ordinal # => "st"
|
22
|
+
# 2.ordinal # => "nd"
|
23
|
+
# 1002.ordinal # => "nd"
|
24
|
+
# 1003.ordinal # => "rd"
|
25
|
+
# -11.ordinal # => "th"
|
26
|
+
# -1001.ordinal # => "st"
|
27
|
+
def ordinal
|
28
|
+
ActiveSupport::Inflector.ordinal(self)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module IntegerExt; end; module IntegerExt::Multiple
|
2
|
+
refine Integer do
|
3
|
+
# Check whether the integer is evenly divisible by the argument.
|
4
|
+
#
|
5
|
+
# 0.multiple_of?(0) #=> true
|
6
|
+
# 6.multiple_of?(5) #=> false
|
7
|
+
# 10.multiple_of?(2) #=> true
|
8
|
+
def multiple_of?(number)
|
9
|
+
number != 0 ? self % number == 0 : zero?
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module IntegerExt; end; module IntegerExt::Time
|
2
|
+
refine Integer do
|
3
|
+
# Enables the use of time calculations and declarations, like <tt>45.minutes +
|
4
|
+
# 2.hours + 4.years</tt>.
|
5
|
+
#
|
6
|
+
# These methods use Time#advance for precise date calculations when using
|
7
|
+
# <tt>from_now</tt>, +ago+, etc. as well as adding or subtracting their
|
8
|
+
# results from a Time object.
|
9
|
+
#
|
10
|
+
# # equivalent to Time.now.advance(months: 1)
|
11
|
+
# 1.month.from_now
|
12
|
+
#
|
13
|
+
# # equivalent to Time.now.advance(years: 2)
|
14
|
+
# 2.years.from_now
|
15
|
+
#
|
16
|
+
# # equivalent to Time.now.advance(months: 4, years: 5)
|
17
|
+
# (4.months + 5.years).from_now
|
18
|
+
#
|
19
|
+
# While these methods provide precise calculation when used as in the examples
|
20
|
+
# above, care should be taken to note that this is not true if the result of
|
21
|
+
# +months+, +years+, etc is converted before use:
|
22
|
+
#
|
23
|
+
# # equivalent to 30.days.to_i.from_now
|
24
|
+
# 1.month.to_i.from_now
|
25
|
+
#
|
26
|
+
# # equivalent to 365.25.days.to_f.from_now
|
27
|
+
# 1.year.to_f.from_now
|
28
|
+
#
|
29
|
+
# In such cases, Ruby's core
|
30
|
+
# Date[http://ruby-doc.org/stdlib/libdoc/date/rdoc/Date.html] and
|
31
|
+
# Time[http://ruby-doc.org/stdlib/libdoc/time/rdoc/Time.html] should be used for precision
|
32
|
+
# date and time arithmetic.
|
33
|
+
def months
|
34
|
+
ActiveSupport::Duration.new(self * 30.days, [[:months, self]])
|
35
|
+
end
|
36
|
+
# alias :month :months
|
37
|
+
|
38
|
+
def years
|
39
|
+
ActiveSupport::Duration.new(self * 365.25.days, [[:years, self]])
|
40
|
+
end
|
41
|
+
# alias :year :years
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module KernelExt; end; module KernelExt::Agnostics
|
2
|
+
refine Object do
|
3
|
+
# Makes backticks behave (somewhat more) similarly on all platforms.
|
4
|
+
# On win32 `nonexistent_command` raises Errno::ENOENT; on Unix, the
|
5
|
+
# spawned shell prints a message to stderr and sets $?. We emulate
|
6
|
+
# Unix on the former but not the latter.
|
7
|
+
def `(command) #:nodoc:
|
8
|
+
super
|
9
|
+
rescue Errno::ENOENT => e
|
10
|
+
STDERR.puts "#$0: #{e}"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module KernelExt; end; module KernelExt::Debugger
|
2
|
+
refine Kernel do
|
3
|
+
unless respond_to?(:debugger)
|
4
|
+
# Starts a debugging session if the +debugger+ gem has been loaded (call rails server --debugger to do load it).
|
5
|
+
def debugger
|
6
|
+
message = "\n***** Debugger requested, but was not available (ensure the debugger gem is listed in Gemfile/installed as gem): Start server with --debugger to enable *****\n"
|
7
|
+
defined?(Rails) ? Rails.logger.info(message) : $stderr.puts(message)
|
8
|
+
end
|
9
|
+
# alias breakpoint debugger unless respond_to?(:breakpoint)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
module KernelExt; end; module KernelExt::Reporting
|
2
|
+
require 'rbconfig'
|
3
|
+
|
4
|
+
refine Kernel do
|
5
|
+
# Sets $VERBOSE to nil for the duration of the block and back to its original
|
6
|
+
# value afterwards.
|
7
|
+
#
|
8
|
+
# silence_warnings do
|
9
|
+
# value = noisy_call # no warning voiced
|
10
|
+
# end
|
11
|
+
#
|
12
|
+
# noisy_call # warning voiced
|
13
|
+
def silence_warnings
|
14
|
+
with_warnings(nil) { yield }
|
15
|
+
end
|
16
|
+
|
17
|
+
# Sets $VERBOSE to +true+ for the duration of the block and back to its
|
18
|
+
# original value afterwards.
|
19
|
+
def enable_warnings
|
20
|
+
with_warnings(true) { yield }
|
21
|
+
end
|
22
|
+
|
23
|
+
# Sets $VERBOSE for the duration of the block and back to its original
|
24
|
+
# value afterwards.
|
25
|
+
def with_warnings(flag)
|
26
|
+
old_verbose, $VERBOSE = $VERBOSE, flag
|
27
|
+
yield
|
28
|
+
ensure
|
29
|
+
$VERBOSE = old_verbose
|
30
|
+
end
|
31
|
+
|
32
|
+
# For compatibility
|
33
|
+
def silence_stderr #:nodoc:
|
34
|
+
silence_stream(STDERR) { yield }
|
35
|
+
end
|
36
|
+
|
37
|
+
# Silences any stream for the duration of the block.
|
38
|
+
#
|
39
|
+
# silence_stream(STDOUT) do
|
40
|
+
# puts 'This will never be seen'
|
41
|
+
# end
|
42
|
+
#
|
43
|
+
# puts 'But this will'
|
44
|
+
def silence_stream(stream)
|
45
|
+
old_stream = stream.dup
|
46
|
+
stream.reopen(RbConfig::CONFIG['host_os'] =~ /mswin|mingw/ ? 'NUL:' : '/dev/null')
|
47
|
+
stream.sync = true
|
48
|
+
yield
|
49
|
+
ensure
|
50
|
+
stream.reopen(old_stream)
|
51
|
+
end
|
52
|
+
|
53
|
+
# Blocks and ignores any exception passed as argument if raised within the block.
|
54
|
+
#
|
55
|
+
# suppress(ZeroDivisionError) do
|
56
|
+
# 1/0
|
57
|
+
# puts 'This code is NOT reached'
|
58
|
+
# end
|
59
|
+
#
|
60
|
+
# puts 'This code gets executed and nothing related to ZeroDivisionError was seen'
|
61
|
+
def suppress(*exception_classes)
|
62
|
+
begin yield
|
63
|
+
rescue Exception => e
|
64
|
+
raise unless exception_classes.any? { |cls| e.kind_of?(cls) }
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
# Captures the given stream and returns it:
|
69
|
+
#
|
70
|
+
# stream = capture(:stdout) { puts 'Cool' }
|
71
|
+
# stream # => "Cool\n"
|
72
|
+
def capture(stream)
|
73
|
+
begin
|
74
|
+
stream = stream.to_s
|
75
|
+
eval "$#{stream} = StringIO.new"
|
76
|
+
yield
|
77
|
+
result = eval("$#{stream}").string
|
78
|
+
ensure
|
79
|
+
eval("$#{stream} = #{stream.upcase}")
|
80
|
+
end
|
81
|
+
|
82
|
+
result
|
83
|
+
end
|
84
|
+
# alias :silence :capture
|
85
|
+
|
86
|
+
# Silences both STDOUT and STDERR, even for subprocesses.
|
87
|
+
#
|
88
|
+
# quietly { system 'bundle install' }
|
89
|
+
def quietly
|
90
|
+
silence_stream(STDOUT) do
|
91
|
+
silence_stream(STDERR) do
|
92
|
+
yield
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module LoadErrorExt
|
2
|
+
refine LoadError do
|
3
|
+
REGEXPS = [
|
4
|
+
/^no such file to load -- (.+)$/i,
|
5
|
+
/^Missing \w+ (?:file\s*)?([^\s]+.rb)$/i,
|
6
|
+
/^Missing API definition file in (.+)$/i,
|
7
|
+
/^cannot load such file -- (.+)$/i,
|
8
|
+
]
|
9
|
+
|
10
|
+
unless method_defined?(:path)
|
11
|
+
def path
|
12
|
+
@path ||= begin
|
13
|
+
REGEXPS.find do |regex|
|
14
|
+
message =~ regex
|
15
|
+
end
|
16
|
+
$1
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def is_missing?(location)
|
22
|
+
location.sub(/\.rb$/, '') == path.sub(/\.rb$/, '')
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
MissingSourceFile = LoadError
|
27
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
module LoggerExt
|
2
|
+
require 'active_support/refinements/core_ext/class/attribute_accessors'
|
3
|
+
require 'active_support/deprecation'
|
4
|
+
|
5
|
+
ActiveSupport::Deprecation.warn 'this file is deprecated and will be removed'
|
6
|
+
|
7
|
+
# Adds the 'around_level' method to Logger.
|
8
|
+
refine Logger do
|
9
|
+
def self.define_around_helper(level)
|
10
|
+
module_eval <<-end_eval, __FILE__, __LINE__ + 1
|
11
|
+
def around_#{level}(before_message, after_message) # def around_debug(before_message, after_message, &block)
|
12
|
+
self.#{level}(before_message) # self.debug(before_message)
|
13
|
+
return_value = yield(self) # return_value = yield(self)
|
14
|
+
self.#{level}(after_message) # self.debug(after_message)
|
15
|
+
return_value # return_value
|
16
|
+
end # end
|
17
|
+
end_eval
|
18
|
+
end
|
19
|
+
[:debug, :info, :error, :fatal].each {|level| define_around_helper(level) }
|
20
|
+
end
|
21
|
+
|
22
|
+
require 'logger'
|
23
|
+
|
24
|
+
# Extensions to the built-in Ruby logger.
|
25
|
+
#
|
26
|
+
# If you want to use the default log formatter as defined in the Ruby core, then you
|
27
|
+
# will need to set the formatter for the logger as in:
|
28
|
+
#
|
29
|
+
# logger.formatter = Formatter.new
|
30
|
+
#
|
31
|
+
# You can then specify the datetime format, for example:
|
32
|
+
#
|
33
|
+
# logger.datetime_format = "%Y-%m-%d"
|
34
|
+
#
|
35
|
+
# Note: This logger is deprecated in favor of ActiveSupport::BufferedLogger
|
36
|
+
refine Logger do
|
37
|
+
##
|
38
|
+
# :singleton-method:
|
39
|
+
# Set to false to disable the silencer
|
40
|
+
cattr_accessor :silencer
|
41
|
+
self.silencer = true
|
42
|
+
|
43
|
+
# Silences the logger for the duration of the block.
|
44
|
+
def silence(temporary_level = Logger::ERROR)
|
45
|
+
if silencer
|
46
|
+
begin
|
47
|
+
old_logger_level, self.level = level, temporary_level
|
48
|
+
yield self
|
49
|
+
ensure
|
50
|
+
self.level = old_logger_level
|
51
|
+
end
|
52
|
+
else
|
53
|
+
yield self
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# alias :old_datetime_format= :datetime_format=
|
58
|
+
# Logging date-time format (string passed to +strftime+). Ignored if the formatter
|
59
|
+
# does not respond to datetime_format=.
|
60
|
+
def datetime_format=(format)
|
61
|
+
formatter.datetime_format = format if formatter.respond_to?(:datetime_format=)
|
62
|
+
end
|
63
|
+
|
64
|
+
# alias :old_datetime_format :datetime_format
|
65
|
+
# Get the logging datetime format. Returns nil if the formatter does not support
|
66
|
+
# datetime formatting.
|
67
|
+
def datetime_format
|
68
|
+
formatter.datetime_format if formatter.respond_to?(:datetime_format)
|
69
|
+
end
|
70
|
+
|
71
|
+
# alias :old_initialize :initialize
|
72
|
+
# Overwrite initialize to set a default formatter.
|
73
|
+
def initialize(*args)
|
74
|
+
old_initialize(*args)
|
75
|
+
self.formatter = SimpleFormatter.new
|
76
|
+
end
|
77
|
+
|
78
|
+
# Simple formatter which only displays the message.
|
79
|
+
refine SimpleFormatter do
|
80
|
+
# This method is invoked when a log event occurs
|
81
|
+
def call(severity, timestamp, progname, msg)
|
82
|
+
"#{String === msg ? msg : msg.inspect}\n"
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'active_support/refinements/core_ext/module/aliasing'
|
2
|
+
require 'active_support/refinements/core_ext/module/introspection'
|
3
|
+
require 'active_support/refinements/core_ext/module/anonymous'
|
4
|
+
require 'active_support/refinements/core_ext/module/reachable'
|
5
|
+
require 'active_support/refinements/core_ext/module/attribute_accessors'
|
6
|
+
require 'active_support/refinements/core_ext/module/attr_internal'
|
7
|
+
require 'active_support/refinements/core_ext/module/delegation'
|
8
|
+
require 'active_support/refinements/core_ext/module/deprecation'
|
9
|
+
require 'active_support/refinements/core_ext/module/remove_method'
|
10
|
+
require 'active_support/refinements/core_ext/module/qualified_const'
|
@@ -0,0 +1,69 @@
|
|
1
|
+
class Module
|
2
|
+
# Encapsulates the common pattern of:
|
3
|
+
#
|
4
|
+
# alias_method :foo_without_feature, :foo
|
5
|
+
# alias_method :foo, :foo_with_feature
|
6
|
+
#
|
7
|
+
# With this, you simply do:
|
8
|
+
#
|
9
|
+
# alias_method_chain :foo, :feature
|
10
|
+
#
|
11
|
+
# And both aliases are set up for you.
|
12
|
+
#
|
13
|
+
# Query and bang methods (foo?, foo!) keep the same punctuation:
|
14
|
+
#
|
15
|
+
# alias_method_chain :foo?, :feature
|
16
|
+
#
|
17
|
+
# is equivalent to
|
18
|
+
#
|
19
|
+
# alias_method :foo_without_feature?, :foo?
|
20
|
+
# alias_method :foo?, :foo_with_feature?
|
21
|
+
#
|
22
|
+
# so you can safely chain foo, foo?, and foo! with the same feature.
|
23
|
+
def alias_method_chain(target, feature)
|
24
|
+
# Strip out punctuation on predicates or bang methods since
|
25
|
+
# e.g. target?_without_feature is not a valid method name.
|
26
|
+
aliased_target, punctuation = target.to_s.sub(/([?!=])$/, ''), $1
|
27
|
+
yield(aliased_target, punctuation) if block_given?
|
28
|
+
|
29
|
+
with_method = "#{aliased_target}_with_#{feature}#{punctuation}"
|
30
|
+
without_method = "#{aliased_target}_without_#{feature}#{punctuation}"
|
31
|
+
|
32
|
+
alias_method without_method, target
|
33
|
+
alias_method target, with_method
|
34
|
+
|
35
|
+
case
|
36
|
+
when public_method_defined?(without_method)
|
37
|
+
public target
|
38
|
+
when protected_method_defined?(without_method)
|
39
|
+
protected target
|
40
|
+
when private_method_defined?(without_method)
|
41
|
+
private target
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# Allows you to make aliases for attributes, which includes
|
46
|
+
# getter, setter, and query methods.
|
47
|
+
#
|
48
|
+
# class Content < ActiveRecord::Base
|
49
|
+
# # has a title attribute
|
50
|
+
# end
|
51
|
+
#
|
52
|
+
# class Email < Content
|
53
|
+
# alias_attribute :subject, :title
|
54
|
+
# end
|
55
|
+
#
|
56
|
+
# e = Email.find(1)
|
57
|
+
# e.title # => "Superstars"
|
58
|
+
# e.subject # => "Superstars"
|
59
|
+
# e.subject? # => true
|
60
|
+
# e.subject = "Megastars"
|
61
|
+
# e.title # => "Megastars"
|
62
|
+
def alias_attribute(new_name, old_name)
|
63
|
+
module_eval <<-STR, __FILE__, __LINE__ + 1
|
64
|
+
def #{new_name}; self.#{old_name}; end # def subject; self.title; end
|
65
|
+
def #{new_name}?; self.#{old_name}?; end # def subject?; self.title?; end
|
66
|
+
def #{new_name}=(v); self.#{old_name} = v; end # def subject=(v); self.title = v; end
|
67
|
+
STR
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module ModuleExt; end; module ModuleExt::Anonymous
|
2
|
+
refine Module do
|
3
|
+
# A module may or may not have a name.
|
4
|
+
#
|
5
|
+
# module M; end
|
6
|
+
# M.name # => "M"
|
7
|
+
#
|
8
|
+
# m = Module.new
|
9
|
+
# m.name # => nil
|
10
|
+
#
|
11
|
+
# A module gets a name when it is first assigned to a constant. Either
|
12
|
+
# via the +module+ or +class+ keyword or by an explicit assignment:
|
13
|
+
#
|
14
|
+
# m = Module.new # creates an anonymous module
|
15
|
+
# M = m # => m gets a name here as a side-effect
|
16
|
+
# m.name # => "M"
|
17
|
+
def anonymous?
|
18
|
+
name.nil?
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|