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,48 @@
1
+ module ObjectExt; end; module ObjectExt::DeepDup
2
+ require 'active_support/refinements/core_ext/object/duplicable'
3
+
4
+ refine Object do
5
+ # Returns a deep copy of object if it's duplicable. If it's
6
+ # not duplicable, returns +self+.
7
+ #
8
+ # object = Object.new
9
+ # dup = object.deep_dup
10
+ # dup.instance_variable_set(:@a, 1)
11
+ #
12
+ # object.instance_variable_defined?(:@a) #=> false
13
+ # dup.instance_variable_defined?(:@a) #=> true
14
+ def deep_dup
15
+ duplicable? ? dup : self
16
+ end
17
+ end
18
+
19
+ refine Array do
20
+ # Returns a deep copy of array.
21
+ #
22
+ # array = [1, [2, 3]]
23
+ # dup = array.deep_dup
24
+ # dup[1][2] = 4
25
+ #
26
+ # array[1][2] #=> nil
27
+ # dup[1][2] #=> 4
28
+ def deep_dup
29
+ map { |it| it.deep_dup }
30
+ end
31
+ end
32
+
33
+ refine Hash do
34
+ # Returns a deep copy of hash.
35
+ #
36
+ # hash = { a: { b: 'b' } }
37
+ # dup = hash.deep_dup
38
+ # dup[:a][:c] = 'c'
39
+ #
40
+ # hash[:a][:c] #=> nil
41
+ # dup[:a][:c] #=> "c"
42
+ def deep_dup
43
+ each_with_object(dup) do |(key, value), hash|
44
+ hash[key.deep_dup] = value.deep_dup
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,92 @@
1
+ module ObjectExt; end; module ObjectExt::Duplicable
2
+ #--
3
+ # Most objects are cloneable, but not all. For example you can't dup +nil+:
4
+ #
5
+ # nil.dup # => TypeError: can't dup NilClass
6
+ #
7
+ # Classes may signal their instances are not duplicable removing +dup+/+clone+
8
+ # or raising exceptions from them. So, to dup an arbitrary object you normally
9
+ # use an optimistic approach and are ready to catch an exception, say:
10
+ #
11
+ # arbitrary_object.dup rescue object
12
+ #
13
+ # Rails dups objects in a few critical spots where they are not that arbitrary.
14
+ # That rescue is very expensive (like 40 times slower than a predicate), and it
15
+ # is often triggered.
16
+ #
17
+ # That's why we hardcode the following cases and check duplicable? instead of
18
+ # using that rescue idiom.
19
+ #++
20
+ refine Object do
21
+ # Can you safely dup this object?
22
+ #
23
+ # False for +nil+, +false+, +true+, symbol, and number objects;
24
+ # true otherwise.
25
+ def duplicable?
26
+ true
27
+ end
28
+ end
29
+
30
+ refine NilClass do
31
+ # +nil+ is not duplicable:
32
+ #
33
+ # nil.duplicable? # => false
34
+ # nil.dup # => TypeError: can't dup NilClass
35
+ def duplicable?
36
+ false
37
+ end
38
+ end
39
+
40
+ refine FalseClass do
41
+ # +false+ is not duplicable:
42
+ #
43
+ # false.duplicable? # => false
44
+ # false.dup # => TypeError: can't dup FalseClass
45
+ def duplicable?
46
+ false
47
+ end
48
+ end
49
+
50
+ refine TrueClass do
51
+ # +true+ is not duplicable:
52
+ #
53
+ # true.duplicable? # => false
54
+ # true.dup # => TypeError: can't dup TrueClass
55
+ def duplicable?
56
+ false
57
+ end
58
+ end
59
+
60
+ refine Symbol do
61
+ # Symbols are not duplicable:
62
+ #
63
+ # :my_symbol.duplicable? # => false
64
+ # :my_symbol.dup # => TypeError: can't dup Symbol
65
+ def duplicable?
66
+ false
67
+ end
68
+ end
69
+
70
+ refine Numeric do
71
+ # Numbers are not duplicable:
72
+ #
73
+ # 3.duplicable? # => false
74
+ # 3.dup # => TypeError: can't dup Fixnum
75
+ def duplicable?
76
+ false
77
+ end
78
+ end
79
+
80
+ require 'bigdecimal'
81
+ refine BigDecimal do
82
+ begin
83
+ BigDecimal.new('4.56').dup
84
+
85
+ def duplicable?
86
+ true
87
+ end
88
+ rescue TypeError
89
+ # can't dup, so use superclass implementation
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,27 @@
1
+ module ObjectExt; end; module ObjectExt::Inclusion
2
+ refine Object do
3
+ # Returns true if this object is included in the argument(s). Argument must be
4
+ # any object which responds to +#include?+ or optionally, multiple arguments can be passed in. Usage:
5
+ #
6
+ # characters = ['Konata', 'Kagami', 'Tsukasa']
7
+ # 'Konata'.in?(characters) # => true
8
+ #
9
+ # character = 'Konata'
10
+ # character.in?('Konata', 'Kagami', 'Tsukasa') # => true
11
+ #
12
+ # This will throw an ArgumentError if a single argument is passed in and it doesn't respond
13
+ # to +#include?+.
14
+ def in?(*args)
15
+ if args.length > 1
16
+ args.include? self
17
+ else
18
+ another_object = args.first
19
+ if another_object.respond_to? :include?
20
+ another_object.include? self
21
+ else
22
+ raise ArgumentError.new 'The single parameter passed to #in? must respond to #include?'
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,30 @@
1
+ module ObjectExt; end; module ObjectExt::InstanceVariables
2
+ refine Object do
3
+ # Returns a hash with string keys that maps instance variable names without "@" to their
4
+ # corresponding values.
5
+ #
6
+ # class C
7
+ # def initialize(x, y)
8
+ # @x, @y = x, y
9
+ # end
10
+ # end
11
+ #
12
+ # C.new(0, 1).instance_values # => {"x" => 0, "y" => 1}
13
+ def instance_values
14
+ Hash[instance_variables.map { |name| [name[1..-1], instance_variable_get(name)] }]
15
+ end
16
+
17
+ # Returns an array of instance variable names including "@".
18
+ #
19
+ # class C
20
+ # def initialize(x, y)
21
+ # @x, @y = x, y
22
+ # end
23
+ # end
24
+ #
25
+ # C.new(0, 1).instance_variable_names # => ["@y", "@x"]
26
+ def instance_variable_names
27
+ instance_variables.map { |var| var.to_s }
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,27 @@
1
+ # Hack to load json gem first so we can overwrite its to_json.
2
+ begin
3
+ require 'json'
4
+ rescue LoadError
5
+ end
6
+
7
+ # The JSON gem adds a few modules to Ruby core classes containing :to_json definition, overwriting
8
+ # their default behavior. That said, we need to define the basic to_json method in all of them,
9
+ # otherwise they will always use to_json gem implementation, which is backwards incompatible in
10
+ # several cases (for instance, the JSON implementation for Hash does not work) with inheritance
11
+ # and consequently classes as ActiveSupport::OrderedHash cannot be serialized to json.
12
+ [Object, Array, FalseClass, Float, Hash, Integer, NilClass, String, TrueClass].each do |klass|
13
+ klass.class_eval do
14
+ # Dumps object in JSON (JavaScript Object Notation). See www.json.org for more info.
15
+ def to_json(options = nil)
16
+ ActiveSupport::JSON.encode(self, options)
17
+ end
18
+ end
19
+ end
20
+
21
+ module Process
22
+ class Status
23
+ def as_json(options = nil)
24
+ { :exitstatus => exitstatus, :pid => pid }
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,60 @@
1
+ module ObjectExt; end; module ObjectExt::ToParam
2
+ refine Object do
3
+ # Alias of <tt>to_s</tt>.
4
+ def to_param
5
+ to_s
6
+ end
7
+ end
8
+
9
+ refine NilClass do
10
+ # Returns +self+.
11
+ def to_param
12
+ self
13
+ end
14
+ end
15
+
16
+ refine TrueClass do
17
+ # Returns +self+.
18
+ def to_param
19
+ self
20
+ end
21
+ end
22
+
23
+ refine FalseClass do
24
+ # Returns +self+.
25
+ def to_param
26
+ self
27
+ end
28
+ end
29
+
30
+ refine Array do
31
+ # Calls <tt>to_param</tt> on all its elements and joins the result with
32
+ # slashes. This is used by <tt>url_for</tt> in Action Pack.
33
+ def to_param
34
+ collect { |e| e.to_param }.join '/'
35
+ end
36
+ end
37
+
38
+ refine Hash do
39
+ # Returns a string representation of the receiver suitable for use as a URL
40
+ # query string:
41
+ #
42
+ # {name: 'David', nationality: 'Danish'}.to_param
43
+ # # => "name=David&nationality=Danish"
44
+ #
45
+ # An optional namespace can be passed to enclose the param names:
46
+ #
47
+ # {name: 'David', nationality: 'Danish'}.to_param('user')
48
+ # # => "user[name]=David&user[nationality]=Danish"
49
+ #
50
+ # The string pairs "key=value" that conform the query string
51
+ # are sorted lexicographically in ascending order.
52
+ #
53
+ # This method is also aliased as +to_query+.
54
+ def to_param(namespace = nil)
55
+ collect do |key, value|
56
+ value.to_query(namespace ? "#{namespace}[#{key}]" : key)
57
+ end.sort * '&'
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,29 @@
1
+ module ObjectExt; end; module ObjectExt::ToQuery
2
+ require 'active_support/refinements/core_ext/object/to_param'
3
+
4
+ refine Object do
5
+ # Converts an object into a string suitable for use as a URL query string, using the given <tt>key</tt> as the
6
+ # param name.
7
+ #
8
+ # Note: This method is defined as a default implementation for all Objects for Hash#to_query to work.
9
+ def to_query(key)
10
+ require 'cgi' unless defined?(CGI) && defined?(CGI::escape)
11
+ "#{CGI.escape(key.to_param)}=#{CGI.escape(to_param.to_s)}"
12
+ end
13
+ end
14
+
15
+ refine Array do
16
+ # Converts an array into a string suitable for use as a URL query string,
17
+ # using the given +key+ as the param name.
18
+ #
19
+ # ['Rails', 'coding'].to_query('hobbies') # => "hobbies%5B%5D=Rails&hobbies%5B%5D=coding"
20
+ def to_query(key)
21
+ prefix = "#{key}[]"
22
+ collect { |value| value.to_query(prefix) }.join '&'
23
+ end
24
+ end
25
+
26
+ refine Hash do
27
+ # alias_method :to_query, :to_param
28
+ end
29
+ end
@@ -0,0 +1,72 @@
1
+ module ObjectExt; end; module ObjectExt::Try
2
+ refine Object do
3
+ # Invokes the public method identified by the symbol +method+, passing it any arguments
4
+ # and/or the block specified, just like the regular Ruby <tt>Object#public_send</tt> does.
5
+ #
6
+ # *Unlike* that method however, a +NoMethodError+ exception will *not* be raised
7
+ # and +nil+ will be returned instead, if the receiving object is a +nil+ object or NilClass.
8
+ #
9
+ # This is also true if the receiving object does not implemented the tried method. It will
10
+ # return +nil+ in that case as well.
11
+ #
12
+ # If try is called without a method to call, it will yield any given block with the object.
13
+ #
14
+ # Please also note that +try+ is defined on +Object+, therefore it won't work with
15
+ # subclasses of +BasicObject+. For example, using try with +SimpleDelegator+ will
16
+ # delegate +try+ to target instead of calling it on delegator itself.
17
+ #
18
+ # Without +try+
19
+ # @person && @person.name
20
+ # or
21
+ # @person ? @person.name : nil
22
+ #
23
+ # With +try+
24
+ # @person.try(:name)
25
+ #
26
+ # +try+ also accepts arguments and/or a block, for the method it is trying
27
+ # Person.try(:find, 1)
28
+ # @people.try(:collect) {|p| p.name}
29
+ #
30
+ # Without a method argument try will yield to the block unless the receiver is nil.
31
+ # @person.try { |p| "#{p.first_name} #{p.last_name}" }
32
+ #
33
+ # +try+ behaves like +Object#public_send+, unless called on +NilClass+.
34
+ def try(*a, &b)
35
+ if a.empty? && block_given?
36
+ yield self
37
+ else
38
+ public_send(*a, &b) if respond_to?(a.first)
39
+ end
40
+ end
41
+
42
+ # Same as #try, but will raise a NoMethodError exception if the receiving is not nil and
43
+ # does not implemented the tried method.
44
+ def try!(*a, &b)
45
+ if a.empty? && block_given?
46
+ yield self
47
+ else
48
+ public_send(*a, &b)
49
+ end
50
+ end
51
+ end
52
+
53
+ refine NilClass do
54
+ # Calling +try+ on +nil+ always returns +nil+.
55
+ # It becomes specially helpful when navigating through associations that may return +nil+.
56
+ #
57
+ # nil.try(:name) # => nil
58
+ #
59
+ # Without +try+
60
+ # @person && !@person.children.blank? && @person.children.first.name
61
+ #
62
+ # With +try+
63
+ # @person.try(:children).try(:first).try(:name)
64
+ def try(*args)
65
+ nil
66
+ end
67
+
68
+ def try!(*args)
69
+ nil
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,44 @@
1
+ module ObjectExt; end; module ObjectExt::WithOptions
2
+ require 'active_support/option_merger'
3
+
4
+ refine Object do
5
+ # An elegant way to factor duplication out of options passed to a series of
6
+ # method calls. Each method called in the block, with the block variable as
7
+ # the receiver, will have its options merged with the default +options+ hash
8
+ # provided. Each method called on the block variable must take an options
9
+ # hash as its final argument.
10
+ #
11
+ # Without <tt>with_options></tt>, this code contains duplication:
12
+ #
13
+ # class Account < ActiveRecord::Base
14
+ # has_many :customers, dependent: :destroy
15
+ # has_many :products, dependent: :destroy
16
+ # has_many :invoices, dependent: :destroy
17
+ # has_many :expenses, dependent: :destroy
18
+ # end
19
+ #
20
+ # Using <tt>with_options</tt>, we can remove the duplication:
21
+ #
22
+ # class Account < ActiveRecord::Base
23
+ # with_options dependent: :destroy do |assoc|
24
+ # assoc.has_many :customers
25
+ # assoc.has_many :products
26
+ # assoc.has_many :invoices
27
+ # assoc.has_many :expenses
28
+ # end
29
+ # end
30
+ #
31
+ # It can also be used with an explicit receiver:
32
+ #
33
+ # I18n.with_options locale: user.locale, scope: 'newsletter' do |i18n|
34
+ # subject i18n.t :subject
35
+ # body i18n.t :body, user_name: user.name
36
+ # end
37
+ #
38
+ # <tt>with_options</tt> can also be nested since the call is forwarded to its receiver.
39
+ # Each nesting level will merge inherited defaults in addition to their own.
40
+ def with_options(options)
41
+ yield ActiveSupport::OptionMerger.new(self, options)
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,19 @@
1
+ module ProcExt
2
+ require "active_support/core_ext/kernel/singleton_class"
3
+ require "active_support/deprecation"
4
+
5
+ refine Proc do
6
+ def bind(object)
7
+ ActiveSupport::Deprecation.warn 'Proc#bind is deprecated and will be removed in future versions', caller
8
+
9
+ block, time = self, Time.now
10
+ object.class_eval do
11
+ method_name = "__bind_#{time.to_i}_#{time.usec}"
12
+ define_method(method_name, &block)
13
+ method = instance_method(method_name)
14
+ remove_method(method_name)
15
+ method
16
+ end.bind(object)
17
+ end
18
+ end
19
+ end