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,19 @@
|
|
|
1
|
+
module PassiveSupport #:nodoc:
|
|
2
|
+
module CoreExtensions #:nodoc:
|
|
3
|
+
module Numeric #:nodoc:
|
|
4
|
+
module Conversions
|
|
5
|
+
# Assumes self represents an offset from UTC in seconds (as returned from Time#utc_offset)
|
|
6
|
+
# and turns this into an +HH:MM formatted string. Example:
|
|
7
|
+
#
|
|
8
|
+
# -21_600.to_utc_offset_s # => "-06:00"
|
|
9
|
+
def to_utc_offset_s(colon=true)
|
|
10
|
+
seconds = self
|
|
11
|
+
sign = (seconds < 0 ? '-' : '+')
|
|
12
|
+
hours = seconds.abs / 3600
|
|
13
|
+
minutes = (seconds.abs % 3600) / 60
|
|
14
|
+
"%s%02d%s%02d" % [ sign, hours, colon ? ":" : "", minutes ]
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
module PassiveSupport #:nodoc:
|
|
2
|
+
module CoreExtensions #:nodoc:
|
|
3
|
+
module Numeric #:nodoc:
|
|
4
|
+
# Enables the use of time calculations and declarations, like 45.minutes + 2.hours + 4.years.
|
|
5
|
+
#
|
|
6
|
+
# These methods use Time#advance for precise date calculations when using from_now, ago, etc.
|
|
7
|
+
# as well as adding or subtracting their results from a Time object. For example:
|
|
8
|
+
#
|
|
9
|
+
# # equivalent to Time.now.advance(:months => 1)
|
|
10
|
+
# 1.month.from_now
|
|
11
|
+
#
|
|
12
|
+
# # equivalent to Time.now.advance(:years => 2)
|
|
13
|
+
# 2.years.from_now
|
|
14
|
+
#
|
|
15
|
+
# # equivalent to Time.now.advance(:months => 4, :years => 5)
|
|
16
|
+
# (4.months + 5.years).from_now
|
|
17
|
+
#
|
|
18
|
+
# While these methods provide precise calculation when used as in the examples above, care
|
|
19
|
+
# should be taken to note that this is not true if the result of `months', `years', etc is
|
|
20
|
+
# converted before use:
|
|
21
|
+
#
|
|
22
|
+
# # equivalent to 30.days.to_i.from_now
|
|
23
|
+
# 1.month.to_i.from_now
|
|
24
|
+
#
|
|
25
|
+
# # equivalent to 365.25.days.to_f.from_now
|
|
26
|
+
# 1.year.to_f.from_now
|
|
27
|
+
#
|
|
28
|
+
# In such cases, Ruby's core
|
|
29
|
+
# Date[http://stdlib.rubyonrails.org/libdoc/date/rdoc/index.html] and
|
|
30
|
+
# Time[http://stdlib.rubyonrails.org/libdoc/time/rdoc/index.html] should be used for precision
|
|
31
|
+
# date and time arithmetic
|
|
32
|
+
module Time
|
|
33
|
+
def seconds
|
|
34
|
+
PassiveSupport::Duration.new(self, [[:seconds, self]])
|
|
35
|
+
end
|
|
36
|
+
alias :second :seconds
|
|
37
|
+
|
|
38
|
+
def minutes
|
|
39
|
+
PassiveSupport::Duration.new(self * 60, [[:seconds, self * 60]])
|
|
40
|
+
end
|
|
41
|
+
alias :minute :minutes
|
|
42
|
+
|
|
43
|
+
def hours
|
|
44
|
+
PassiveSupport::Duration.new(self * 3600, [[:seconds, self * 3600]])
|
|
45
|
+
end
|
|
46
|
+
alias :hour :hours
|
|
47
|
+
|
|
48
|
+
def days
|
|
49
|
+
PassiveSupport::Duration.new(self * 24.hours, [[:days, self]])
|
|
50
|
+
end
|
|
51
|
+
alias :day :days
|
|
52
|
+
|
|
53
|
+
def weeks
|
|
54
|
+
PassiveSupport::Duration.new(self * 7.days, [[:days, self * 7]])
|
|
55
|
+
end
|
|
56
|
+
alias :week :weeks
|
|
57
|
+
|
|
58
|
+
def fortnights
|
|
59
|
+
PassiveSupport::Duration.new(self * 2.weeks, [[:days, self * 14]])
|
|
60
|
+
end
|
|
61
|
+
alias :fortnight :fortnights
|
|
62
|
+
|
|
63
|
+
# Reads best without arguments: 10.minutes.ago
|
|
64
|
+
def ago(time = ::Time.now)
|
|
65
|
+
time - self
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Reads best with argument: 10.minutes.until(time)
|
|
69
|
+
alias :until :ago
|
|
70
|
+
|
|
71
|
+
# Reads best with argument: 10.minutes.since(time)
|
|
72
|
+
def since(time = ::Time.now)
|
|
73
|
+
time + self
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# Reads best without arguments: 10.minutes.from_now
|
|
77
|
+
alias :from_now :since
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
require 'passive_support/core_ext/object/blank'
|
|
2
|
+
require 'passive_support/core_ext/object/conversions'
|
|
3
|
+
require 'passive_support/core_ext/object/extending'
|
|
4
|
+
require 'passive_support/core_ext/object/instance_variables'
|
|
5
|
+
require 'passive_support/core_ext/object/singleton_class'
|
|
6
|
+
require 'passive_support/core_ext/object/misc'
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
class Object
|
|
2
|
+
# An object is blank if it's false, empty, or a whitespace string.
|
|
3
|
+
# For example, "", " ", +nil+, [], and {} are blank.
|
|
4
|
+
#
|
|
5
|
+
# This simplifies:
|
|
6
|
+
#
|
|
7
|
+
# if !address.nil? && !address.empty?
|
|
8
|
+
#
|
|
9
|
+
# ...to:
|
|
10
|
+
#
|
|
11
|
+
# if !address.blank?
|
|
12
|
+
def blank?
|
|
13
|
+
respond_to?(:empty?) ? empty? : !self
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# An object is present if it's not blank.
|
|
17
|
+
def present?
|
|
18
|
+
!blank?
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Returns object if it's #present? otherwise returns nil.
|
|
22
|
+
# object.presence is equivalent to object.present? ? object : nil.
|
|
23
|
+
#
|
|
24
|
+
# This is handy for any representation of objects where blank is the same
|
|
25
|
+
# as not present at all. For example, this simplifies a common check for
|
|
26
|
+
# HTTP POST/query parameters:
|
|
27
|
+
#
|
|
28
|
+
# state = params[:state] if params[:state].present?
|
|
29
|
+
# country = params[:country] if params[:country].present?
|
|
30
|
+
# region = state || country || 'US'
|
|
31
|
+
#
|
|
32
|
+
# ...becomes:
|
|
33
|
+
#
|
|
34
|
+
# region = params[:state].presence || params[:country].presence || 'US'
|
|
35
|
+
def presence
|
|
36
|
+
self if present?
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
class NilClass #:nodoc:
|
|
41
|
+
def blank?
|
|
42
|
+
true
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
class FalseClass #:nodoc:
|
|
47
|
+
def blank?
|
|
48
|
+
true
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
class TrueClass #:nodoc:
|
|
53
|
+
def blank?
|
|
54
|
+
false
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
class Array #:nodoc:
|
|
59
|
+
alias_method :blank?, :empty?
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
class Hash #:nodoc:
|
|
63
|
+
alias_method :blank?, :empty?
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
class String #:nodoc:
|
|
67
|
+
def blank?
|
|
68
|
+
self !~ /\S/
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
class Numeric #:nodoc:
|
|
73
|
+
def blank?
|
|
74
|
+
false
|
|
75
|
+
end
|
|
76
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
class Object
|
|
2
|
+
# Alias of <tt>to_s</tt>.
|
|
3
|
+
def to_param
|
|
4
|
+
to_s
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
# Converts an object into a string suitable for use as a URL query string, using the given <tt>key</tt> as the
|
|
8
|
+
# param name.
|
|
9
|
+
#
|
|
10
|
+
# Note: This method is defined as a default implementation for all Objects for Hash#to_query to work.
|
|
11
|
+
def to_query(key)
|
|
12
|
+
require 'cgi' unless defined?(CGI) && defined?(CGI::escape)
|
|
13
|
+
"#{CGI.escape(key.to_s)}=#{CGI.escape(to_param.to_s)}"
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
class Object
|
|
2
|
+
def remove_subclasses_of(*superclasses) #:nodoc:
|
|
3
|
+
Class.remove_class(*subclasses_of(*superclasses))
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
begin
|
|
7
|
+
ObjectSpace.each_object(Class.new) {}
|
|
8
|
+
|
|
9
|
+
# Exclude this class unless it's a subclass of our supers and is defined.
|
|
10
|
+
# We check defined? in case we find a removed class that has yet to be
|
|
11
|
+
# garbage collected. This also fails for anonymous classes -- please
|
|
12
|
+
# submit a patch if you have a workaround.
|
|
13
|
+
def subclasses_of(*superclasses) #:nodoc:
|
|
14
|
+
subclasses = []
|
|
15
|
+
|
|
16
|
+
superclasses.each do |sup|
|
|
17
|
+
ObjectSpace.each_object(class << sup; self; end) do |k|
|
|
18
|
+
if k != sup && (k.name.blank? || eval("defined?(::#{k}) && ::#{k}.object_id == k.object_id"))
|
|
19
|
+
subclasses << k
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
subclasses
|
|
25
|
+
end
|
|
26
|
+
rescue RuntimeError
|
|
27
|
+
# JRuby and any implementations which cannot handle the objectspace traversal
|
|
28
|
+
# above fall back to this implementation
|
|
29
|
+
def subclasses_of(*superclasses) #:nodoc:
|
|
30
|
+
subclasses = []
|
|
31
|
+
|
|
32
|
+
superclasses.each do |sup|
|
|
33
|
+
ObjectSpace.each_object(Class) do |k|
|
|
34
|
+
if superclasses.any? { |superclass| k < superclass } &&
|
|
35
|
+
(k.name.blank? || eval("defined?(::#{k}) && ::#{k}.object_id == k.object_id"))
|
|
36
|
+
subclasses << k
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
subclasses.uniq!
|
|
40
|
+
end
|
|
41
|
+
subclasses
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def extended_by #:nodoc:
|
|
46
|
+
ancestors = class << self; ancestors end
|
|
47
|
+
ancestors.select { |mod| mod.class == Module } - [ Object, Kernel ]
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def extend_with_included_modules_from(object) #:nodoc:
|
|
51
|
+
object.extended_by.each { |mod| extend mod }
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
unless defined? instance_exec # 1.9
|
|
55
|
+
module InstanceExecMethods #:nodoc:
|
|
56
|
+
end
|
|
57
|
+
include InstanceExecMethods
|
|
58
|
+
|
|
59
|
+
# Evaluate the block with the given arguments within the context of
|
|
60
|
+
# this object, so self is set to the method receiver.
|
|
61
|
+
#
|
|
62
|
+
# From Mauricio's http://eigenclass.org/hiki/bounded+space+instance_exec
|
|
63
|
+
def instance_exec(*args, &block)
|
|
64
|
+
begin
|
|
65
|
+
old_critical, Thread.critical = Thread.critical, true
|
|
66
|
+
n = 0
|
|
67
|
+
n += 1 while respond_to?(method_name = "__instance_exec#{n}")
|
|
68
|
+
InstanceExecMethods.module_eval { define_method(method_name, &block) }
|
|
69
|
+
ensure
|
|
70
|
+
Thread.critical = old_critical
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
begin
|
|
74
|
+
send(method_name, *args)
|
|
75
|
+
ensure
|
|
76
|
+
InstanceExecMethods.module_eval { remove_method(method_name) } rescue nil
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
class Object
|
|
2
|
+
# Available in 1.8.6 and later.
|
|
3
|
+
unless respond_to?(:instance_variable_defined?)
|
|
4
|
+
def instance_variable_defined?(variable)
|
|
5
|
+
instance_variables.include?(variable.to_s)
|
|
6
|
+
end
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
# Returns a hash that maps instance variable names without "@" to their
|
|
10
|
+
# corresponding values. Keys are strings both in Ruby 1.8 and 1.9.
|
|
11
|
+
#
|
|
12
|
+
# class C
|
|
13
|
+
# def initialize(x, y)
|
|
14
|
+
# @x, @y = x, y
|
|
15
|
+
# end
|
|
16
|
+
# end
|
|
17
|
+
#
|
|
18
|
+
# C.new(0, 1).instance_values # => {"x" => 0, "y" => 1}
|
|
19
|
+
def instance_values #:nodoc:
|
|
20
|
+
instance_variables.inject({}) do |values, name|
|
|
21
|
+
values[name.to_s[1..-1]] = instance_variable_get(name)
|
|
22
|
+
values
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Returns an array of instance variable names including "@". They are strings
|
|
27
|
+
# both in Ruby 1.8 and 1.9.
|
|
28
|
+
#
|
|
29
|
+
# class C
|
|
30
|
+
# def initialize(x, y)
|
|
31
|
+
# @x, @y = x, y
|
|
32
|
+
# end
|
|
33
|
+
# end
|
|
34
|
+
#
|
|
35
|
+
# C.new(0, 1).instance_variable_names # => ["@y", "@x"]
|
|
36
|
+
if RUBY_VERSION >= '1.9'
|
|
37
|
+
def instance_variable_names
|
|
38
|
+
instance_variables.map { |var| var.to_s }
|
|
39
|
+
end
|
|
40
|
+
else
|
|
41
|
+
alias_method :instance_variable_names, :instance_variables
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Copies the instance variables of +object+ into +self+.
|
|
45
|
+
#
|
|
46
|
+
# Instance variable names in the +exclude+ array are ignored. If +object+
|
|
47
|
+
# responds to <tt>protected_instance_variables</tt> the ones returned are
|
|
48
|
+
# also ignored. For example, Rails controllers implement that method.
|
|
49
|
+
#
|
|
50
|
+
# In both cases strings and symbols are understood, and they have to include
|
|
51
|
+
# the at sign.
|
|
52
|
+
#
|
|
53
|
+
# class C
|
|
54
|
+
# def initialize(x, y, z)
|
|
55
|
+
# @x, @y, @z = x, y, z
|
|
56
|
+
# end
|
|
57
|
+
#
|
|
58
|
+
# def protected_instance_variables
|
|
59
|
+
# %w(@z)
|
|
60
|
+
# end
|
|
61
|
+
# end
|
|
62
|
+
#
|
|
63
|
+
# a = C.new(0, 1, 2)
|
|
64
|
+
# b = C.new(3, 4, 5)
|
|
65
|
+
#
|
|
66
|
+
# a.copy_instance_variables_from(b, [:@y])
|
|
67
|
+
# # a is now: @x = 3, @y = 1, @z = 2
|
|
68
|
+
def copy_instance_variables_from(object, exclude = []) #:nodoc:
|
|
69
|
+
exclude += object.protected_instance_variables if object.respond_to? :protected_instance_variables
|
|
70
|
+
|
|
71
|
+
vars = object.instance_variables.map(&:to_s) - exclude.map(&:to_s)
|
|
72
|
+
vars.each { |name| instance_variable_set(name, object.instance_variable_get(name)) }
|
|
73
|
+
end
|
|
74
|
+
end
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
class Object
|
|
2
|
+
# Returns +value+ after yielding +value+ to the block. This simplifies the
|
|
3
|
+
# process of constructing an object, performing work on the object, and then
|
|
4
|
+
# returning the object from a method. It is a Ruby-ized realization of the K
|
|
5
|
+
# combinator, courtesy of Mikael Brockman.
|
|
6
|
+
#
|
|
7
|
+
# ==== Examples
|
|
8
|
+
#
|
|
9
|
+
# # Without returning
|
|
10
|
+
# def foo
|
|
11
|
+
# values = []
|
|
12
|
+
# values << "bar"
|
|
13
|
+
# values << "baz"
|
|
14
|
+
# return values
|
|
15
|
+
# end
|
|
16
|
+
#
|
|
17
|
+
# foo # => ['bar', 'baz']
|
|
18
|
+
#
|
|
19
|
+
# # returning with a local variable
|
|
20
|
+
# def foo
|
|
21
|
+
# returning values = [] do
|
|
22
|
+
# values << 'bar'
|
|
23
|
+
# values << 'baz'
|
|
24
|
+
# end
|
|
25
|
+
# end
|
|
26
|
+
#
|
|
27
|
+
# foo # => ['bar', 'baz']
|
|
28
|
+
#
|
|
29
|
+
# # returning with a block argument
|
|
30
|
+
# def foo
|
|
31
|
+
# returning [] do |values|
|
|
32
|
+
# values << 'bar'
|
|
33
|
+
# values << 'baz'
|
|
34
|
+
# end
|
|
35
|
+
# end
|
|
36
|
+
#
|
|
37
|
+
# foo # => ['bar', 'baz']
|
|
38
|
+
def returning(value)
|
|
39
|
+
yield(value)
|
|
40
|
+
value
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Yields <code>x</code> to the block, and then returns <code>x</code>.
|
|
44
|
+
# The primary purpose of this method is to "tap into" a method chain,
|
|
45
|
+
# in order to perform operations on intermediate results within the chain.
|
|
46
|
+
#
|
|
47
|
+
# (1..10).tap { |x| puts "original: #{x.inspect}" }.to_a.
|
|
48
|
+
# tap { |x| puts "array: #{x.inspect}" }.
|
|
49
|
+
# select { |x| x%2 == 0 }.
|
|
50
|
+
# tap { |x| puts "evens: #{x.inspect}" }.
|
|
51
|
+
# map { |x| x*x }.
|
|
52
|
+
# tap { |x| puts "squares: #{x.inspect}" }
|
|
53
|
+
def tap
|
|
54
|
+
yield self
|
|
55
|
+
self
|
|
56
|
+
end unless Object.respond_to?(:tap)
|
|
57
|
+
|
|
58
|
+
# An elegant way to factor duplication out of options passed to a series of
|
|
59
|
+
# method calls. Each method called in the block, with the block variable as
|
|
60
|
+
# the receiver, will have its options merged with the default +options+ hash
|
|
61
|
+
# provided. Each method called on the block variable must take an options
|
|
62
|
+
# hash as its final argument.
|
|
63
|
+
#
|
|
64
|
+
# with_options :order => 'created_at', :class_name => 'Comment' do |post|
|
|
65
|
+
# post.has_many :comments, :conditions => ['approved = ?', true], :dependent => :delete_all
|
|
66
|
+
# post.has_many :unapproved_comments, :conditions => ['approved = ?', false]
|
|
67
|
+
# post.has_many :all_comments
|
|
68
|
+
# end
|
|
69
|
+
#
|
|
70
|
+
# Can also be used with an explicit receiver:
|
|
71
|
+
#
|
|
72
|
+
# map.with_options :controller => "people" do |people|
|
|
73
|
+
# people.connect "/people", :action => "index"
|
|
74
|
+
# people.connect "/people/:id", :action => "show"
|
|
75
|
+
# end
|
|
76
|
+
#
|
|
77
|
+
def with_options(options)
|
|
78
|
+
yield ActiveSupport::OptionMerger.new(self, options)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# A duck-type assistant method. For example, Active Support extends Date
|
|
82
|
+
# to define an acts_like_date? method, and extends Time to define
|
|
83
|
+
# acts_like_time?. As a result, we can do "x.acts_like?(:time)" and
|
|
84
|
+
# "x.acts_like?(:date)" to do duck-type-safe comparisons, since classes that
|
|
85
|
+
# we want to act like Time simply need to define an acts_like_time? method.
|
|
86
|
+
def acts_like?(duck)
|
|
87
|
+
respond_to? "acts_like_#{duck}?"
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
end
|