Search code examples
runtimecreateprocesseiffel

Eiffel: create at runtime a typed object


Trying to create an object which is decided @runtime I have a similar situation as:

class ZOO

feature

    animals: LINKED_LIST[ANIMAL]

    default_create
        do
            create animals.make
            animals.extend(create {LION})
            animals.extend(create {SERPENT})
            animals.extend(create {BIRD})
        end

    open
        local
            l_sector: ZOO_SECTOR[ANIMAL]
        do
            across
                animals as animal
            loop
                create {ZOO_SECTOR[animal.item.generating_type]} l_sector
            end
        end

on create {ZOO_SECTOR[animal.item.generating_type]} l_sector the compiler disagrees with me, I tried with l_type: TYPE[ANIMAL] and create {ZOO_SECTOR[l_type]} l_sector which neither works. Am I obligated to do something like that? which will be for me a contradiction with polymorphism flexibility, I think I'm missing a mecanism/statement

open
    local
        l_sector: ZOO_SECTOR[ANIMAL]
    do
        across
            animals as animal
        loop
            if attached {LION} animal.item then
                create {ZOO_SECTOR[LION]} l_sector
            else if attached {SERPENT} animal.item then
                create {ZOO_SECTOR[SERPENT]} l_sector
            else
                .....
        end
    end

Solution

  • Eiffel type system relies on the class structure, and the class structure is fixed at compile time. It might be possible to add types dynamically (e.g., it should be possible to come up with a solution using reflection), but this is not directly expressible in the language itself.

    If it is allowed for an animal to know its zoo sector, the ZOO_SECTOR types could be encoded directly in the animal class:

    class ANIMAL feature ...
        sector: ZOO_SECTOR [like Current] do create Result end
    end
    

    Due to the use of like Current, there is no need to add any new code in descendants. The loop from the example would become

    across
        animals as animal
    loop
        l_sector := animal.item.sector
    end
    

    giving ZOO_SECTOR [LION] for an item of type LION, etc.