Eiffel: способ оценить выражение типа STRING, такое как `eval`

Есть ли способ оценить выражение STRING в Eiffel? (Я знаю, что это большой источник ошибок ... но мощный механизм!)

Ищу способ сделать общий механизм настройки для полей и классов базы данных, я пытаюсь сделать что-то вроде.

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

Я знаю, что могу сделать это с помощью агентов, но мне это кажется менее общим, поскольку мне нужно определять каждую функцию 2 раза.

  • в fields_mapping
  • в другом fields_mapping у меня есть для преобразования JSON
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
48
1

Ответы 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.

Удивительно ... нужно время, чтобы интегрировать его в мой проект и попробовать! Еще раз спасибо ....

Pipo 10.10.2018 20:26

Другие вопросы по теме