How could I improve this code so there is no duplicate code and it would allow me to add new similar methods dynamically?
def fabric_ids=(property_name)
@fabric_ids = [] if @fabric_ids.blank?
@fabric_ids << $property_values[property_name]
end
def work_ids=(property_name)
@work_ids = [] if @work_ids.blank?
@work_ids << $property_values[property_name]
end
def type_ids=(property_name)
@type_ids = [] if @type_ids.blank?
@type_ids << $property_values[property_name]
end
You can define your methods dynamically, using Module#define_method
, like this:
%w(fabric_ids work_ids type_ids).each do |name|
define_method("#{name}=") do |property_name|
instance_variable_set(name, []) if instance_variable_get(name).blank?
instance_variable_get(name) << $property_values[property_name]
end
end
You might want to consider organizing this as hash. Here's one way to do that.
Code
ITEMS = [:fabric, :work, :kind]
class MyClass
attr_accessor :ids
def initialize
@ids = Hash.new { |h,k| h[k] = [] }
end
ITEMS.each do |item|
define_method("#{item.to_s}_properties") { properties_by_key(item) }
define_method("add_#{item.to_s}_properties") { |*property_names|
add_properties_by_key(item, *property_names) }
end
private
def add_properties_by_key(key, *property_names)
property_names.each { |name| self.ids[key] << $property_values[name] }
end
def properties_by_key(key)
self.ids[key]
end
end
p MyClass.instance_methods(false)
# [:ids, :ids=,
# :fabric_properties, :add_fabric_properties,
# :work_properties, :add_work_properties,
# :kind_properties, :add_kind_properties]
Example
$property_values = { color: "blue", weight: "heavy", cost: "average" }
my_class = MyClass.new
my_class.add_fabric_properties(:color, :weight, :cost)
my_class.add_work_properties(:weight, :cost)
my_class.add_kind_properties(:color)
p my_class.fabric_properties #=> ["blue", "heavy", "average"]
p my_class.work_properties #=> ["heavy", "average"]
p my_class.kind_properties #=> ["blue"]
my_class.add_kind_properties(:cost)
p my_class.kind_properties #=> ["blue", "average"]
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.