我不确定'action'是否是正确的词,但假设你有一个看起来像这样的方法:
def schedule_jobs
User.schedule!
Activity.schedule!
Event.schedule!
Notify.schedule!
end
我正在寻找的是在schedule_jobs方法上运行某种函数,它将返回4。
我想要它,因为我会创建一个测试,确保安排4个工作,但是,当我下周添加Report.schedule!
时,需要我手动更改4到5。
做一些像这样的事情:
class Foo
JOBS_TO_SCHEDULE = %w(
User
Activity
Event
Notify
).freeze
def schedule_jobs
self.class::JOBS_TO_SCHEDULE.each do |job_to_schedule|
job_to_schedule.constantize.schedule!
end
end
end
然后,你总是可以询问Foo::JOBS_TO_SCHEDULE
,看看你预计安排了多少工作。
跟进评论:
也不需要调用#constantize,因为你可以引用数组中的常量而不是使用字符串。
假设我有一个类Foo
像这样:
class Foo
JOBS_TO_SCHEDULE = %w(
Baz
).freeze
def schedule_jobs
JOBS_TO_SCHEDULE.each do |job_to_schedule|
puts job_to_schedule.class.name
job_to_schedule.schedule!
end
end
end
而且我有一个类,Baz
像这样:
class Baz
class << self
def schedule!
puts "scheduled!"
end
end
end
如果我打电话给Foo.new.schedule_jobs
然后我得到:
> Foo.new.schedule_jobs
String
NoMethodError: undefined method `schedule!' for "Baz":String
可以看出,job_to_schedule
是一个String
(因为,这就是%w()
所做的,创造了一系列String
s)。所以,我得到了NoMethodError
,因为String
没有回应schedule!
。
但是,如果我包括constantize
,就像这样:
class Foo
JOBS_TO_SCHEDULE = %w(
Baz
).freeze
def schedule_jobs
JOBS_TO_SCHEDULE.each do |job_to_schedule|
puts job_to_schedule.class.name
job_to_schedule.constantize.schedule!
end
end
end
然后,当调用Foo.new.schedule_jobs
时,我得到:
> Foo.new.schedule_jobs
String
scheduled!
因此,需要调用#constantize
。
现在,我可以这样做:
class Foo
JOBS_TO_SCHEDULE = [
Baz
].freeze
def schedule_jobs
JOBS_TO_SCHEDULE.each do |job_to_schedule|
puts job_to_schedule.class.name
job_to_schedule.schedule!
end
end
end
在这种情况下,如果我做Foo.new.schedule_jobs
,我得到:
> Foo.new.schedule_jobs
Class
scheduled!
一切都很好。
不需要self.class - 实例方法可以直接访问常量。
假设我有一个类Bar
像这样:
class Bar < Foo
end
如果我做Bar.new.schedule_jobs
,那么我得到:
> Bar.new.schedule_jobs
String
scheduled!
所以,评论是正确的。
引用数组中的常量可能会触发Ruby的自动加载机制,这可能是不可取的。我用的是符号。
如果我有:
class Foo
JOBS_TO_SCHEDULE = [
:baz
].freeze
def schedule_jobs
JOBS_TO_SCHEDULE.each do |job_to_schedule|
puts job_to_schedule.class.name
job_to_schedule.schedule!
end
end
end
然后当我做Foo.new.schedule_jobs
时,我得到:
> Foo.new.schedule_jobs
Symbol
NoMethodError: undefined method `schedule!' for :baz:Symbol
正如所料。当然,这也不起作用:
class Foo
JOBS_TO_SCHEDULE = [
:baz
].freeze
def schedule_jobs
JOBS_TO_SCHEDULE.each do |job_to_schedule|
puts job_to_schedule.class.name
job_to_schedule.constantize.schedule!
end
end
end
当我做Foo.new.schedule_jobs
时,我得到:
> Foo.new.schedule_jobs
Symbol
NoMethodError: undefined method `constantize' for :baz:Symbol
因为我试图对一个符号进行限制。我可以:
class Foo
JOBS_TO_SCHEDULE = [
:baz
].freeze
def schedule_jobs
JOBS_TO_SCHEDULE.each do |job_to_schedule|
puts job_to_schedule.class.name
job_to_schedule.to_s.camelize.constantize.schedule!
end
end
end
在这种情况下,当我做Foo.new.schedule_jobs
时,我得到:
> Foo.new.schedule_jobs
Symbol
scheduled!
一切都很好。 (但是,我必须做.to_s.camelize
,这是一些打字,我宁愿避免。)