有没有一种方法可以评估Eiffel中的STRING表达式? (我知道一个大的错误源,但是机制很强大!)
寻找一种对数据库字段和类进行通用设置的方法,我正在尝试执行类似的操作。
fields_mapping: HASH_TABLE [ANY, STRING]
do
create Result.make (10)
Result.put (name, "name")
Result.put (surname, "surname")
...
end
set_fields
do
across
fields_mapping as field
loop
eval("set_" + field.key + "(" + field.item + ")")
end
end
我知道我可以使用代理来做到这一点,但对我来说似乎不太通用,因为我必须两次定义每个函数
fields_mapping
fields_mapping
中答案 0 :(得分:1)
Eiffel的现有实现是编译而不是解释。因此,不支持对任意表达式的求值。使用反射类仍然可以使用给定值更新任意对象字段:
update_object (field_values: HASH_TABLE [ANY, STRING]; target: ANY)
-- Update fields of object `target` with values from `field_values`.
local
object: REFLECTED_REFERENCE_OBJECT
fields: like field_properties
position: like {REFLECTED_OBJECT}.field_count
do
create object.make (target)
fields := field_properties (object.dynamic_type)
across
field_values as v
loop
if attached fields [v.key] as f then
position := f.position
if {REFLECTOR}.field_conforms_to (v.item.generating_type.type_id, f.type_id) then
inspect object.field_type (position)
when {REFLECTOR_CONSTANTS}.integer_32_type then
object.set_integer_32_field (position, {INTEGER_32} / v.item)
when ... then
-- Other basic types.
when {REFLECTOR_CONSTANTS}.reference_type then
object.set_reference_field (position, v.item)
else
print ("Unhandled field type%N")
end
else
print ("Field type mismatch%N")
end
end
end
end
上面的代码有点简化,因为它不处理类型SPECIAL
和TUPLE
以及用户定义的扩展类型。该代码依赖于记录类型信息的帮助程序功能,因此下次不应从头开始重新计算它:
field_properties (type_id: like {TYPE [ANY]}.type_id):
HASH_TABLE [TUPLE [position: INTEGER; type_id: INTEGER], STRING]
-- Positions and types of fields indexed by their name
-- for a specified type ID `type_id`.
local
i: like {REFLECTOR}.field_count_of_type
do
Result := field_positions_table [type_id]
if not attached Result then
from
i := {REFLECTOR}.field_count_of_type (type_id)
create Result.make (i)
field_positions_table.force (Result, type_id)
until
i <= 0
loop
Result [{REFLECTOR}.field_name_of_type (i, type_id)] :=
[i, {REFLECTOR}.field_static_type_of_type (i, type_id)]
i := i - 1
end
end
end
field_positions_table: HASH_TABLE [HASH_TABLE
[TUPLE [position: INTEGER; type_id: INTEGER], STRING], INTEGER]
once
create Result.make (1)
end
使用特征update_object
并假定对象x
分别具有类型foo
和bar
的字段INTEGER_32
和detachable STRING_8
,以下代码
field_values: HASH_TABLE [ANY, STRING]
do
create field_values.make (10)
field_values ["foo"] := {INTEGER_32} 5
field_values ["bar"] := " bottles"
update_object (field_values, x)
print (x.foo)
print (x.bar)
将打印5 bottles
,而不管对象x
的先前状态如何。