Search code examples
eiffel

Eiffel: syntax error on multiple Generic constraint


As per this documentation, I'm trying to constrain a Generic parameter to 2 classes and need a default_create creation procedure call in my implementation.

I'm getting a Syntax error from compiler on the select clause. Why is that so?

I thought first that calling default_create will call the G one which could be a merge/renaming/etc. but seems that on that level I have to call either one of both or both renamed which makes sense for me. But why does this syntax fail?

The context and my code is following:

deferred class
    IDENTIFIABLE_CASH[G -> {IDENTIFIABLE[ANY],
                            DB_ENTITY select default_create end} create default_create end]

inherit
    DB_SERVICE_CASH[G]


feature -- Access

    cash_from_identifier (an_identifier: like {IDENTIFIABLE_DB_ENTITY[ANY]}.identifier): G
            -- Returns firt entity found like given an_identifier (like operator is used)
        local
            l_qry: COMPOSED_SQL_QUERY
        do
            across
                cash is l_item
            loop
                if l_item.identifier.is_equal(an_identifier) then
                    Result := l_item
                end
            end
            if not attached Result then
                create l_qry.make (item_prototype)
                l_qry.add_constraint (create {FIELD_CONSTRAINT}.make (Void, identifier_db_column_name, {CONSTRAINT}.Like_operator, an_identifier))
                load_entities (l_qry)
                if items.count > 0 then
                    Result := items.first
                else
                    create Result
                    check
                        item_not_found: False
                    end
                end

                cash.extend (Result)
            end
        end

Solution

  • The page states that select clause is not part of the standard, and rename should be used instead. In other words, it's sufficient to rename default_create for at least one of two constraint classes, and use one version of the feature, e.g. default_create:

    G -> {IDENTIFIABLE[ANY], DB_ENTITY rename default_create as d end}
         create default_create end
    

    In the above case, Result can be created with create Result or create Result.default_create. The second version could be used as well:

    G -> {IDENTIFIABLE[ANY], DB_ENTITY rename default_create as d end}
         create d end
    

    Now Result can be created only with create Result.d. Finally, both creation procedures can be listed:

    G -> {IDENTIFIABLE[ANY], DB_ENTITY rename default_create as d end}
         create default_create, d end
    

    The last variant allow using either create Result.default_create or create Result.d.