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,3 @@
1
+ require 'active_support/refinements/core_ext/integer/multiple'
2
+ require 'active_support/refinements/core_ext/integer/inflections'
3
+ require 'active_support/refinements/core_ext/integer/time'
@@ -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,4 @@
1
+ require 'active_support/refinements/core_ext/kernel/reporting'
2
+ require 'active_support/refinements/core_ext/kernel/agnostics'
3
+ require 'active_support/refinements/core_ext/kernel/debugger'
4
+ require 'active_support/refinements/core_ext/kernel/singleton_class'
@@ -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,8 @@
1
+ module KernelExt; end; module KernelExt::SingletonClass
2
+ refine Kernel do
3
+ # class_eval on an object acts like singleton_class.class_eval.
4
+ def class_eval(*args, &block)
5
+ singleton_class.class_eval(*args, &block)
6
+ end
7
+ end
8
+ 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