emipair-delayed_job 2.0.3.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.
- data/.gitignore +2 -0
- data/MIT-LICENSE +20 -0
- data/README.textile +213 -0
- data/Rakefile +33 -0
- data/VERSION +1 -0
- data/benchmarks.rb +33 -0
- data/contrib/delayed_job.monitrc +14 -0
- data/contrib/delayed_job_multiple.monitrc +23 -0
- data/emipair-delayed_job.gemspec +25 -0
- data/generators/delayed_job/delayed_job_generator.rb +22 -0
- data/generators/delayed_job/templates/migration.rb +21 -0
- data/generators/delayed_job/templates/script +5 -0
- data/init.rb +1 -0
- data/lib/delayed/backend/active_record.rb +90 -0
- data/lib/delayed/backend/base.rb +111 -0
- data/lib/delayed/backend/data_mapper.rb +147 -0
- data/lib/delayed/backend/mongo_mapper.rb +110 -0
- data/lib/delayed/command.rb +109 -0
- data/lib/delayed/message_sending.rb +22 -0
- data/lib/delayed/performable_method.rb +62 -0
- data/lib/delayed/railtie.rb +10 -0
- data/lib/delayed/recipes.rb +31 -0
- data/lib/delayed/tasks.rb +15 -0
- data/lib/delayed/worker.rb +214 -0
- data/lib/delayed_job.rb +15 -0
- data/lib/passive_support.rb +4 -0
- data/lib/passive_support/basic_object.rb +16 -0
- data/lib/passive_support/core_ext.rb +8 -0
- data/lib/passive_support/core_ext/class.rb +1 -0
- data/lib/passive_support/core_ext/class/attribute_accessors.rb +57 -0
- data/lib/passive_support/core_ext/date.rb +10 -0
- data/lib/passive_support/core_ext/date/behavior.rb +42 -0
- data/lib/passive_support/core_ext/date/calculations.rb +241 -0
- data/lib/passive_support/core_ext/date/conversions.rb +107 -0
- data/lib/passive_support/core_ext/date_time.rb +12 -0
- data/lib/passive_support/core_ext/date_time/calculations.rb +126 -0
- data/lib/passive_support/core_ext/date_time/conversions.rb +107 -0
- data/lib/passive_support/core_ext/enumerable.rb +120 -0
- data/lib/passive_support/core_ext/kernel.rb +5 -0
- data/lib/passive_support/core_ext/kernel/agnostics.rb +11 -0
- data/lib/passive_support/core_ext/kernel/daemonizing.rb +7 -0
- data/lib/passive_support/core_ext/kernel/debugger.rb +16 -0
- data/lib/passive_support/core_ext/kernel/reporting.rb +59 -0
- data/lib/passive_support/core_ext/kernel/requires.rb +24 -0
- data/lib/passive_support/core_ext/module.rb +20 -0
- data/lib/passive_support/core_ext/module/aliasing.rb +74 -0
- data/lib/passive_support/core_ext/module/attr_accessor_with_default.rb +31 -0
- data/lib/passive_support/core_ext/module/attr_internal.rb +32 -0
- data/lib/passive_support/core_ext/module/delegation.rb +135 -0
- data/lib/passive_support/core_ext/module/inclusion.rb +30 -0
- data/lib/passive_support/core_ext/module/introspection.rb +90 -0
- data/lib/passive_support/core_ext/module/loading.rb +23 -0
- data/lib/passive_support/core_ext/module/model_naming.rb +25 -0
- data/lib/passive_support/core_ext/module/synchronization.rb +39 -0
- data/lib/passive_support/core_ext/numeric.rb +9 -0
- data/lib/passive_support/core_ext/numeric/bytes.rb +50 -0
- data/lib/passive_support/core_ext/numeric/conversions.rb +19 -0
- data/lib/passive_support/core_ext/numeric/time.rb +81 -0
- data/lib/passive_support/core_ext/object.rb +6 -0
- data/lib/passive_support/core_ext/object/blank.rb +76 -0
- data/lib/passive_support/core_ext/object/conversions.rb +15 -0
- data/lib/passive_support/core_ext/object/extending.rb +80 -0
- data/lib/passive_support/core_ext/object/instance_variables.rb +74 -0
- data/lib/passive_support/core_ext/object/misc.rb +90 -0
- data/lib/passive_support/core_ext/object/singleton_class.rb +13 -0
- data/lib/passive_support/core_ext/string.rb +1 -0
- data/lib/passive_support/core_ext/string/constantize.rb +7 -0
- data/lib/passive_support/core_ext/time.rb +46 -0
- data/lib/passive_support/core_ext/time/behavior.rb +13 -0
- data/lib/passive_support/core_ext/time/calculations.rb +313 -0
- data/lib/passive_support/core_ext/time/conversions.rb +90 -0
- data/lib/passive_support/core_ext/time/zones.rb +86 -0
- data/lib/passive_support/duration.rb +100 -0
- data/lib/passive_support/ordered_hash.rb +158 -0
- data/rails/init.rb +5 -0
- data/recipes/delayed_job.rb +1 -0
- data/spec/backend/active_record_job_spec.rb +46 -0
- data/spec/backend/data_mapper_job_spec.rb +16 -0
- data/spec/backend/mongo_mapper_job_spec.rb +94 -0
- data/spec/backend/shared_backend_spec.rb +268 -0
- data/spec/delayed_method_spec.rb +58 -0
- data/spec/performable_method_spec.rb +42 -0
- data/spec/sample_jobs.rb +25 -0
- data/spec/setup/active_record.rb +33 -0
- data/spec/setup/data_mapper.rb +24 -0
- data/spec/setup/mongo_mapper.rb +17 -0
- data/spec/spec_helper.rb +19 -0
- data/spec/story_spec.rb +17 -0
- data/spec/worker_spec.rb +225 -0
- data/tasks/jobs.rake +1 -0
- metadata +323 -0
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
module PassiveSupport #:nodoc:
|
|
2
|
+
module CoreExtensions #:nodoc:
|
|
3
|
+
module DateTime #:nodoc:
|
|
4
|
+
# Converting datetimes to formatted strings, dates, and times.
|
|
5
|
+
module Conversions
|
|
6
|
+
def self.append_features(base) #:nodoc:
|
|
7
|
+
base.class_eval do
|
|
8
|
+
alias_method :default_inspect, :inspect
|
|
9
|
+
alias_method :to_default_s, :to_s unless (instance_methods(false) & [:to_s, 'to_s']).empty?
|
|
10
|
+
|
|
11
|
+
# Ruby 1.9 has DateTime#to_time which internally relies on Time. We define our own #to_time which allows
|
|
12
|
+
# DateTimes outside the range of what can be created with Time.
|
|
13
|
+
remove_method :to_time if instance_methods.include?(:to_time)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
super
|
|
17
|
+
|
|
18
|
+
base.class_eval do
|
|
19
|
+
alias_method :to_s, :to_formatted_s
|
|
20
|
+
alias_method :inspect, :readable_inspect
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Convert to a formatted string. See Time::DATE_FORMATS for predefined formats.
|
|
25
|
+
#
|
|
26
|
+
# This method is aliased to <tt>to_s</tt>.
|
|
27
|
+
#
|
|
28
|
+
# === Examples
|
|
29
|
+
# datetime = DateTime.civil(2007, 12, 4, 0, 0, 0, 0) # => Tue, 04 Dec 2007 00:00:00 +0000
|
|
30
|
+
#
|
|
31
|
+
# datetime.to_formatted_s(:db) # => "2007-12-04 00:00:00"
|
|
32
|
+
# datetime.to_s(:db) # => "2007-12-04 00:00:00"
|
|
33
|
+
# datetime.to_s(:number) # => "20071204000000"
|
|
34
|
+
# datetime.to_formatted_s(:short) # => "04 Dec 00:00"
|
|
35
|
+
# datetime.to_formatted_s(:long) # => "December 04, 2007 00:00"
|
|
36
|
+
# datetime.to_formatted_s(:long_ordinal) # => "December 4th, 2007 00:00"
|
|
37
|
+
# datetime.to_formatted_s(:rfc822) # => "Tue, 04 Dec 2007 00:00:00 +0000"
|
|
38
|
+
#
|
|
39
|
+
# == Adding your own datetime formats to to_formatted_s
|
|
40
|
+
# DateTime formats are shared with Time. You can add your own to the
|
|
41
|
+
# Time::DATE_FORMATS hash. Use the format name as the hash key and
|
|
42
|
+
# either a strftime string or Proc instance that takes a time or
|
|
43
|
+
# datetime argument as the value.
|
|
44
|
+
#
|
|
45
|
+
# # config/initializers/time_formats.rb
|
|
46
|
+
# Time::DATE_FORMATS[:month_and_year] = "%B %Y"
|
|
47
|
+
# Time::DATE_FORMATS[:short_ordinal] = lambda { |time| time.strftime("%B #{time.day.ordinalize}") }
|
|
48
|
+
def to_formatted_s(format = :default)
|
|
49
|
+
return to_default_s unless formatter = ::Time::DATE_FORMATS[format]
|
|
50
|
+
formatter.respond_to?(:call) ? formatter.call(self).to_s : strftime(formatter)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Returns the +utc_offset+ as an +HH:MM formatted string. Examples:
|
|
54
|
+
#
|
|
55
|
+
# datetime = DateTime.civil(2000, 1, 1, 0, 0, 0, Rational(-6, 24))
|
|
56
|
+
# datetime.formatted_offset # => "-06:00"
|
|
57
|
+
# datetime.formatted_offset(false) # => "-0600"
|
|
58
|
+
def formatted_offset(colon = true, alternate_utc_string = nil)
|
|
59
|
+
utc? && alternate_utc_string || utc_offset.to_utc_offset_s(colon)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Overrides the default inspect method with a human readable one, e.g., "Mon, 21 Feb 2005 14:30:00 +0000"
|
|
63
|
+
def readable_inspect
|
|
64
|
+
to_s(:rfc822)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Converts self to a Ruby Date object; time portion is discarded
|
|
68
|
+
def to_date
|
|
69
|
+
::Date.new(year, month, day)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Attempts to convert self to a Ruby Time object; returns self if out of range of Ruby Time class
|
|
73
|
+
# If self has an offset other than 0, self will just be returned unaltered, since there's no clean way to map it to a Time
|
|
74
|
+
def to_time
|
|
75
|
+
self.offset == 0 ? ::Time.utc_time(year, month, day, hour, min, sec) : self
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# To be able to keep Times, Dates and DateTimes interchangeable on conversions
|
|
79
|
+
def to_datetime
|
|
80
|
+
self
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# Converts datetime to an appropriate format for use in XML
|
|
84
|
+
def xmlschema
|
|
85
|
+
strftime("%Y-%m-%dT%H:%M:%S%Z")
|
|
86
|
+
end if RUBY_VERSION < '1.9'
|
|
87
|
+
|
|
88
|
+
# Converts self to a floating-point number of seconds since the Unix epoch
|
|
89
|
+
def to_f
|
|
90
|
+
seconds_since_unix_epoch.to_f
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# Converts self to an integer number of seconds since the Unix epoch
|
|
94
|
+
def to_i
|
|
95
|
+
seconds_since_unix_epoch.to_i
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
private
|
|
99
|
+
|
|
100
|
+
def seconds_since_unix_epoch
|
|
101
|
+
seconds_per_day = 86_400
|
|
102
|
+
(self - ::DateTime.civil(1970)) * seconds_per_day
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
require 'passive_support/ordered_hash'
|
|
2
|
+
|
|
3
|
+
module Enumerable
|
|
4
|
+
# Ruby 1.8.7 introduces group_by, but the result isn't ordered. Override it.
|
|
5
|
+
remove_method(:group_by) if [].respond_to?(:group_by) && RUBY_VERSION < '1.9'
|
|
6
|
+
|
|
7
|
+
# Collect an enumerable into sets, grouped by the result of a block. Useful,
|
|
8
|
+
# for example, for grouping records by date.
|
|
9
|
+
#
|
|
10
|
+
# Example:
|
|
11
|
+
#
|
|
12
|
+
# latest_transcripts.group_by(&:day).each do |day, transcripts|
|
|
13
|
+
# p "#{day} -> #{transcripts.map(&:class).join(', ')}"
|
|
14
|
+
# end
|
|
15
|
+
# "2006-03-01 -> Transcript"
|
|
16
|
+
# "2006-02-28 -> Transcript"
|
|
17
|
+
# "2006-02-27 -> Transcript, Transcript"
|
|
18
|
+
# "2006-02-26 -> Transcript, Transcript"
|
|
19
|
+
# "2006-02-25 -> Transcript"
|
|
20
|
+
# "2006-02-24 -> Transcript, Transcript"
|
|
21
|
+
# "2006-02-23 -> Transcript"
|
|
22
|
+
def group_by
|
|
23
|
+
assoc = PassiveSupport::OrderedHash.new
|
|
24
|
+
|
|
25
|
+
each do |element|
|
|
26
|
+
key = yield(element)
|
|
27
|
+
|
|
28
|
+
if assoc.has_key?(key)
|
|
29
|
+
assoc[key] << element
|
|
30
|
+
else
|
|
31
|
+
assoc[key] = [element]
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
assoc
|
|
36
|
+
end unless [].respond_to?(:group_by)
|
|
37
|
+
|
|
38
|
+
# Calculates a sum from the elements. Examples:
|
|
39
|
+
#
|
|
40
|
+
# payments.sum { |p| p.price * p.tax_rate }
|
|
41
|
+
# payments.sum(&:price)
|
|
42
|
+
#
|
|
43
|
+
# The latter is a shortcut for:
|
|
44
|
+
#
|
|
45
|
+
# payments.inject { |sum, p| sum + p.price }
|
|
46
|
+
#
|
|
47
|
+
# It can also calculate the sum without the use of a block.
|
|
48
|
+
#
|
|
49
|
+
# [5, 15, 10].sum # => 30
|
|
50
|
+
# ["foo", "bar"].sum # => "foobar"
|
|
51
|
+
# [[1, 2], [3, 1, 5]].sum => [1, 2, 3, 1, 5]
|
|
52
|
+
#
|
|
53
|
+
# The default sum of an empty list is zero. You can override this default:
|
|
54
|
+
#
|
|
55
|
+
# [].sum(Payment.new(0)) { |i| i.amount } # => Payment.new(0)
|
|
56
|
+
#
|
|
57
|
+
def sum(identity = 0, &block)
|
|
58
|
+
if block_given?
|
|
59
|
+
map(&block).sum(identity)
|
|
60
|
+
else
|
|
61
|
+
inject { |sum, element| sum + element } || identity
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Iterates over a collection, passing the current element *and* the
|
|
66
|
+
# +memo+ to the block. Handy for building up hashes or
|
|
67
|
+
# reducing collections down to one object. Examples:
|
|
68
|
+
#
|
|
69
|
+
# %w(foo bar).each_with_object({}) { |str, hsh| hsh[str] = str.upcase } #=> {'foo' => 'FOO', 'bar' => 'BAR'}
|
|
70
|
+
#
|
|
71
|
+
# *Note* that you can't use immutable objects like numbers, true or false as
|
|
72
|
+
# the memo. You would think the following returns 120, but since the memo is
|
|
73
|
+
# never changed, it does not.
|
|
74
|
+
#
|
|
75
|
+
# (1..5).each_with_object(1) { |value, memo| memo *= value } # => 1
|
|
76
|
+
#
|
|
77
|
+
def each_with_object(memo, &block)
|
|
78
|
+
returning memo do |m|
|
|
79
|
+
each do |element|
|
|
80
|
+
block.call(element, m)
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end unless [].respond_to?(:each_with_object)
|
|
84
|
+
|
|
85
|
+
# Convert an enumerable to a hash. Examples:
|
|
86
|
+
#
|
|
87
|
+
# people.index_by(&:login)
|
|
88
|
+
# => { "nextangle" => <Person ...>, "chade-" => <Person ...>, ...}
|
|
89
|
+
# people.index_by { |person| "#{person.first_name} #{person.last_name}" }
|
|
90
|
+
# => { "Chade- Fowlersburg-e" => <Person ...>, "David Heinemeier Hansson" => <Person ...>, ...}
|
|
91
|
+
#
|
|
92
|
+
def index_by
|
|
93
|
+
inject({}) do |accum, elem|
|
|
94
|
+
accum[yield(elem)] = elem
|
|
95
|
+
accum
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# Returns true if the collection has more than 1 element. Functionally equivalent to collection.size > 1.
|
|
100
|
+
# Works with a block too ala any?, so people.many? { |p| p.age > 26 } # => returns true if more than 1 person is over 26.
|
|
101
|
+
def many?(&block)
|
|
102
|
+
size = block_given? ? select(&block).size : self.size
|
|
103
|
+
size > 1
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# Returns true if none of the elements match the given block.
|
|
107
|
+
#
|
|
108
|
+
# success = responses.none? {|r| r.status / 100 == 5 }
|
|
109
|
+
#
|
|
110
|
+
# This is a builtin method in Ruby 1.8.7 and later.
|
|
111
|
+
def none?(&block)
|
|
112
|
+
!any?(&block)
|
|
113
|
+
end unless [].respond_to?(:none?)
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
# The negative of the Enumerable#include?. Returns true if the collection does not include the object.
|
|
117
|
+
def exclude?(object)
|
|
118
|
+
!include?(object)
|
|
119
|
+
end
|
|
120
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
class Object
|
|
2
|
+
# Makes backticks behave (somewhat more) similarly on all platforms.
|
|
3
|
+
# On win32 `nonexistent_command` raises Errno::ENOENT; on Unix, the
|
|
4
|
+
# spawned shell prints a message to stderr and sets $?. We emulate
|
|
5
|
+
# Unix on the former but not the latter.
|
|
6
|
+
def `(command) #:nodoc:
|
|
7
|
+
super
|
|
8
|
+
rescue Errno::ENOENT => e
|
|
9
|
+
STDERR.puts "#$0: #{e}"
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module Kernel
|
|
2
|
+
unless respond_to?(:debugger)
|
|
3
|
+
# Starts a debugging session if ruby-debug has been loaded (call script/server --debugger to do load it).
|
|
4
|
+
def debugger
|
|
5
|
+
message = "\n***** Debugger requested, but was not available: Start server with --debugger to enable *****\n"
|
|
6
|
+
defined?(Rails) ? Rails.logger.info(message) : $stderr.puts(message)
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
undef :breakpoint if respond_to?(:breakpoint)
|
|
11
|
+
def breakpoint
|
|
12
|
+
message = "\n***** The 'breakpoint' command has been renamed 'debugger' -- please change *****\n"
|
|
13
|
+
defined?(Rails) ? Rails.logger.info(message) : $stderr.puts(message)
|
|
14
|
+
debugger
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
module Kernel
|
|
2
|
+
# Sets $VERBOSE to nil for the duration of the block and back to its original value afterwards.
|
|
3
|
+
#
|
|
4
|
+
# silence_warnings do
|
|
5
|
+
# value = noisy_call # no warning voiced
|
|
6
|
+
# end
|
|
7
|
+
#
|
|
8
|
+
# noisy_call # warning voiced
|
|
9
|
+
def silence_warnings
|
|
10
|
+
old_verbose, $VERBOSE = $VERBOSE, nil
|
|
11
|
+
yield
|
|
12
|
+
ensure
|
|
13
|
+
$VERBOSE = old_verbose
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Sets $VERBOSE to true for the duration of the block and back to its original value afterwards.
|
|
17
|
+
def enable_warnings
|
|
18
|
+
old_verbose, $VERBOSE = $VERBOSE, true
|
|
19
|
+
yield
|
|
20
|
+
ensure
|
|
21
|
+
$VERBOSE = old_verbose
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# For compatibility
|
|
25
|
+
def silence_stderr #:nodoc:
|
|
26
|
+
silence_stream(STDERR) { yield }
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Silences any stream for the duration of the block.
|
|
30
|
+
#
|
|
31
|
+
# silence_stream(STDOUT) do
|
|
32
|
+
# puts 'This will never be seen'
|
|
33
|
+
# end
|
|
34
|
+
#
|
|
35
|
+
# puts 'But this will'
|
|
36
|
+
def silence_stream(stream)
|
|
37
|
+
old_stream = stream.dup
|
|
38
|
+
stream.reopen(RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'NUL:' : '/dev/null')
|
|
39
|
+
stream.sync = true
|
|
40
|
+
yield
|
|
41
|
+
ensure
|
|
42
|
+
stream.reopen(old_stream)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Blocks and ignores any exception passed as argument if raised within the block.
|
|
46
|
+
#
|
|
47
|
+
# suppress(ZeroDivisionError) do
|
|
48
|
+
# 1/0
|
|
49
|
+
# puts "This code is NOT reached"
|
|
50
|
+
# end
|
|
51
|
+
#
|
|
52
|
+
# puts "This code gets executed and nothing related to ZeroDivisionError was seen"
|
|
53
|
+
def suppress(*exception_classes)
|
|
54
|
+
begin yield
|
|
55
|
+
rescue Exception => e
|
|
56
|
+
raise unless exception_classes.any? { |cls| e.kind_of?(cls) }
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module Kernel
|
|
2
|
+
# Require a library with fallback to RubyGems. Warnings during library
|
|
3
|
+
# loading are silenced to increase signal/noise for application warnings.
|
|
4
|
+
def require_library_or_gem(library_name)
|
|
5
|
+
silence_warnings do
|
|
6
|
+
begin
|
|
7
|
+
require library_name
|
|
8
|
+
rescue LoadError => cannot_require
|
|
9
|
+
# 1. Requiring the module is unsuccessful, maybe it's a gem and nobody required rubygems yet. Try.
|
|
10
|
+
begin
|
|
11
|
+
require 'rubygems'
|
|
12
|
+
rescue LoadError => rubygems_not_installed
|
|
13
|
+
raise cannot_require
|
|
14
|
+
end
|
|
15
|
+
# 2. Rubygems is installed and loaded. Try to load the library again
|
|
16
|
+
begin
|
|
17
|
+
require library_name
|
|
18
|
+
rescue LoadError => gem_not_installed
|
|
19
|
+
raise cannot_require
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
require 'passive_support/core_ext/module/inclusion'
|
|
2
|
+
require 'passive_support/core_ext/module/delegation'
|
|
3
|
+
require 'passive_support/core_ext/module/introspection'
|
|
4
|
+
require 'passive_support/core_ext/module/loading'
|
|
5
|
+
require 'passive_support/core_ext/module/aliasing'
|
|
6
|
+
require 'passive_support/core_ext/module/model_naming'
|
|
7
|
+
require 'passive_support/core_ext/module/synchronization'
|
|
8
|
+
|
|
9
|
+
module PassiveSupport
|
|
10
|
+
module CoreExtensions
|
|
11
|
+
# Various extensions for the Ruby core Module class.
|
|
12
|
+
module Module
|
|
13
|
+
# Nothing here. Only defined for API documentation purposes.
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
class Module
|
|
19
|
+
include PassiveSupport::CoreExtensions::Module
|
|
20
|
+
end
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
module PassiveSupport
|
|
2
|
+
module CoreExtensions
|
|
3
|
+
module Module
|
|
4
|
+
# Encapsulates the common pattern of:
|
|
5
|
+
#
|
|
6
|
+
# alias_method :foo_without_feature, :foo
|
|
7
|
+
# alias_method :foo, :foo_with_feature
|
|
8
|
+
#
|
|
9
|
+
# With this, you simply do:
|
|
10
|
+
#
|
|
11
|
+
# alias_method_chain :foo, :feature
|
|
12
|
+
#
|
|
13
|
+
# And both aliases are set up for you.
|
|
14
|
+
#
|
|
15
|
+
# Query and bang methods (foo?, foo!) keep the same punctuation:
|
|
16
|
+
#
|
|
17
|
+
# alias_method_chain :foo?, :feature
|
|
18
|
+
#
|
|
19
|
+
# is equivalent to
|
|
20
|
+
#
|
|
21
|
+
# alias_method :foo_without_feature?, :foo?
|
|
22
|
+
# alias_method :foo?, :foo_with_feature?
|
|
23
|
+
#
|
|
24
|
+
# so you can safely chain foo, foo?, and foo! with the same feature.
|
|
25
|
+
def alias_method_chain(target, feature)
|
|
26
|
+
# Strip out punctuation on predicates or bang methods since
|
|
27
|
+
# e.g. target?_without_feature is not a valid method name.
|
|
28
|
+
aliased_target, punctuation = target.to_s.sub(/([?!=])$/, ''), $1
|
|
29
|
+
yield(aliased_target, punctuation) if block_given?
|
|
30
|
+
|
|
31
|
+
with_method, without_method = "#{aliased_target}_with_#{feature}#{punctuation}", "#{aliased_target}_without_#{feature}#{punctuation}"
|
|
32
|
+
|
|
33
|
+
alias_method without_method, target
|
|
34
|
+
alias_method target, with_method
|
|
35
|
+
|
|
36
|
+
case
|
|
37
|
+
when public_method_defined?(without_method)
|
|
38
|
+
public target
|
|
39
|
+
when protected_method_defined?(without_method)
|
|
40
|
+
protected target
|
|
41
|
+
when private_method_defined?(without_method)
|
|
42
|
+
private target
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Allows you to make aliases for attributes, which includes
|
|
47
|
+
# getter, setter, and query methods.
|
|
48
|
+
#
|
|
49
|
+
# Example:
|
|
50
|
+
#
|
|
51
|
+
# class Content < ActiveRecord::Base
|
|
52
|
+
# # has a title attribute
|
|
53
|
+
# end
|
|
54
|
+
#
|
|
55
|
+
# class Email < Content
|
|
56
|
+
# alias_attribute :subject, :title
|
|
57
|
+
# end
|
|
58
|
+
#
|
|
59
|
+
# e = Email.find(1)
|
|
60
|
+
# e.title # => "Superstars"
|
|
61
|
+
# e.subject # => "Superstars"
|
|
62
|
+
# e.subject? # => true
|
|
63
|
+
# e.subject = "Megastars"
|
|
64
|
+
# e.title # => "Megastars"
|
|
65
|
+
def alias_attribute(new_name, old_name)
|
|
66
|
+
module_eval <<-STR, __FILE__, __LINE__ + 1
|
|
67
|
+
def #{new_name}; self.#{old_name}; end # def subject; self.title; end
|
|
68
|
+
def #{new_name}?; self.#{old_name}?; end # def subject?; self.title?; end
|
|
69
|
+
def #{new_name}=(v); self.#{old_name} = v; end # def subject=(v); self.title = v; end
|
|
70
|
+
STR
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|