Pipo
Pipo

Reputation: 5083

Eiffel: Invalid constraint for formal generic paramete

Following with strange patterns for some, can't I do that? The compiler says Invalid constraint for formal generic parameter

class PARENT[G -> CHILD[like Current]]

feature -- Access

    children: LIST[G]

end

class CHILD[H -> PARENT[like Current]]

feature -- Access

    father: H
end

to be able to do something like

class WIDOW_PARENT

inherit
    PARENT[BLACK_CHILD]

end

class BLACK_CHILD

inherit 
    CHILD[WIDOW_PARENT]

end

If I don't do it with genericity, I'd have to redefine the children collection from

instead of only specify it in the inherit clause... Hope it makes sense

Update

As I solved it with Alexanders answer, I'm stuck further doing a conformity check. I'm trying to set an HTTP router depending on entities and if its a child entity it should be able to do a http://host:port/entity/child_entity/id to get all child entities from entity. For that I'd like to add to the generic router a check. On something like ANY_PARENT_DB_ENTITY such as

if ({G}).conforms_to ({CHILD_DB_ENTITY[ANY_PARENT_DB_ENTITY]}) then
    friend.act_like_a_father 
else
    friend.act_like_a_mate
end

Upvotes: 0

Views: 76

Answers (2)

Pipo
Pipo

Reputation: 5083

Being still the best solution for me, the only solution to my whole pattern is to redefine in my router class the set_handler method with

CHILD_DB_ENTITY

deferred class
    CHILD_DB_ENTITY[H -> PARENT_DB_ENTITY[CHILD_DB_ENTITY[H]]]

inherit
    DB_ENTITY

feature 

    parent: H

ENTITY_HANDLER

ENTITY_HANDLER[G -> DB_ENTITY, H -> DB_SERVICE[G] create make end]

feature

        item_prototype: detachable G

        set_handler
            do
                setting_url_("http://host:port/" + {like item_prototype}.out)
                ...
            end
end -- Class

CHILD_ENTITY_HANDLER

CHILD_ENTITY_HANDLER[G -> CHILD_DB_ENTITY[PARENT_DB_ENTITY[G]], H -> DB_SERVICE[G]]

inherit
    ENTITY_HANDLDER
        redefine
            set_handler
        end

feature

        set_handler
            do
                Precursor
                setting_url_("http://host:port/" + ({like item_prototype}).out + "/" + ({like item_prototype.parent}).out + "/{id}")
            end

end -- Class

PARENT_ENTITY_HANDLER

PARENT_ENTITY_HANDLER[G -> PARENT_DB_ENTITY[CHILD_DB_ENTITY[G]], H -> DB_SERVICE[G]]

inherit
    ENTITY_HANDLDER
        redefine
            set_handler
        end

feature

        set_handler
            do
                Precursor
                setting_url_("http://host:port/" + ({like item_prototype}).out + "/" + ({like item_prototype.children.item}).out + "/{id}")
                -- children being a LINKED_LIST[PARENT_DB_ENTITY]
            end

end -- Class

I hoped there was a way to get it with polymorphism in same class, but it also makes sense to have to redefine it that way...

Upvotes: 0

Alexander Kogtenkov
Alexander Kogtenkov

Reputation: 5790

In contemporary Eiffel, anchored types cannot be used in formal generic constraints, thus the error. It's still possible to have mutual constraints by repeating class types explicitly:

class PARENT [G -> CHILD [PARENT [G]]]
class CHILD  [H -> PARENT [CHILD [H]]]

With this change, the example compiles.

Upvotes: 2

Related Questions