我正在尝试创建一个简单的类,该类在设置或读取字段时自动将一组字段转换为指定的 Ruby 类型。
这是我到目前为止所拥有的,它有效。但是,它不是 DRY,而且我的元编程是初级的。
有没有更好、更清洁的方法来实现这一点?
class BasicModel
def self.fields(params)
params.each do |name, type|
# Define field writers
define_method("#{name}=") {|v| @fields[name] = v}
# Define field readers
case type.name
when 'String'
define_method(name) { @fields[name].to_s }
when 'Integer'
define_method(name) { @fields[name].to_i }
when 'Float'
define_method(name) { @fields[name].to_f }
else raise 'invalid field type'
end
end
end
fields(
name: String,
qty: Integer,
weight: Float
)
def initialize
@fields = {}
end
end
# specification
m = BasicModel.new
m.name => ""
m.name = 2 => 2
m.name => "2"
m.qty => 0
m.qty = "1" => "1"
m.qty => 1
m.weight => 0.0
m.weight = 10 => 10
m.weight => 10.0
对读者和作者进行类型转换的缺点/优点是什么?例如,以下代码在 writer 上进行类型转换,而不是在 reader 上(上图)。我也把case
里面的define_method
。
class BasicModel
def self.fields(params)
params.each do |name, type|
define_method(name) { @fields[name] }
define_method("#{name}=") do |val|
@fields[name] = case type.name
when 'Integer' then val.to_i
when 'Float' then val.to_f
when 'String' then val.to_s
else raise 'invalid field type'
end
end
end
end
我在想一个可能的问题是决策树(例如案例语句)可能应该被排除在define_method
. 我假设每次设置/读取字段时都会对语句进行毫无意义的评估。这个对吗?