我有很多方法完全相同,但需要使用特定名称定义它们。所以我在调用每个format_
方法的方法中尝试了以下内容:
['street', 'postcode', 'email', 'type', 'subtype', 'dsc', 'duration'].each do |attribute|
define_method("self.format_#{attribute}") do |value|
return cleanup(value)
end
end
之前,我对数组中的每个元素都有一个单独的方法:
def self.format_street value
return cleanup(value)
end
如何获得第一个块来为数组中的每个元素生成方法?
这里的新实施基于Andrew Marshall的回答:
def self.analyze_input! formatted_information, category
analyzed_information = {}
attributes = eval(category).attributes
['inst_number', 'name', 'head_of_department', 'street', 'city', 'phone', 'classification', 'sub_classification'].each do |attribute|
define_singleton_method(:"analyze_#{attribute}") do |value|
value
end
end
formatted_information.each do |key, value|
if attributes.include?(key)
analyzed_information[:"#{key}"] = send("analyze_#{key}", value)
end
end
end
答案 0 :(得分:4)
将self.
放在要定义的方法的名称中没有您想要的效果,它实际上创建了一个具有该名称的方法:
define_method(:'self.foo') { 'bar' }
self.foo # undefined method
send('self.foo') #=> "bar"
而是省略self.
,而是使用define_singleton_method
:
attributes = %w[street postcode email type subtype dsc duration]
attributes.each do |attribute|
define_singleton_method(:"format_#{attribute}") do |value|
cleanup(value)
end
end
您还必须省略块中的显式return
,因为它将从方法返回,而不是块。隐含的回报就足够了。
答案 1 :(得分:1)
执行:
class << self
['street', 'postcode', 'email', 'type', 'subtype', 'dsc', 'duration'].each do |attribute|
define_method("format_#{attribute}") do |value|
cleanup(value)
end
end
end
答案 2 :(得分:1)
由于方法完全相同,因此使用Module#alias_method
或使用BasicObject#method_missing
创建别名将是最直接的方法。
使用alias_method
NAMES= ['street', 'postcode', 'email', 'type', 'subtype', 'dsc', 'duration']
class Clean
class << self
def cleanup(value)
puts "cleanup #{value}"
end
NAMES.each {|n| alias_method "format_#{n}", :cleanup}
def doit
format_street(5)
format_type(13)
end
end
end
Clean.methods(false) # =>[:cleanup, :doit, :format_street, :format_postcode, \
# => :format_email, :format_type, :format_subtype, \
# => :format_dsc, :format_duration]
Clean.doit
# => cleanup 5
# => cleanup 13
Clean.format_dsc(3) # => cleanup 3
使用method_missing
class Clean
class << self
@names = NAMES.map {|e| "format_#{e}".to_sym}
def cleanup(value)
puts "cleanup #{value}"
end
def method_missing(name, *args)
if @names.include? name
cleanup args.first
else
super
end
end
def doit
format_street(5)
format_type(13)
end
end
end
Clean.doit
# => cleanup 5
# => cleanup 13
Clean.format_email(7) # => cleanup 7
Clean.cat(9) # NoMethodError: undefined method `cat' for Clean:Class