Eiffel: лучший способ сравнить типы, не получая при этом - PullRequest
0 голосов
/ 29 июня 2019

Получил Catcall, пытаясь сравнить 2 типа, как я могу это сделать, избегая прохождения через другой не выделенный метод (например, string, class_id или тому подобное)?

enter image description here

SIT_UTIL

    class_name_lowercase (a_string: STRING): STRING
            -- a copy lowercased and pruned from preceding '!'
        do
            Result := a_string
            if Result.index_of('!', 1) = 1 then
                Result := Result.substring (2, Result.count)
                Result.to_lower
            else
                Result := Result.as_lower
            end
        ensure
            instance_free: class
        end

CLIENT_CLASS

    relationship_from_secondary_type_equal (a_type: like relationships.item.secondary_type): detachable like relationships.item
            -- Returns first instance of found relationship secondary type which equals given one
        do
            across
                relationships as l_rel
            until
                Result /= Void
            loop
--              if attached (a_type / l_rel.item.secondary_type) then -- Don't want conformance but equality

--              if attached (a_type.is_equal (l_rel.item.secondary_type)) then -- tried but as is_equal needs a like Current => Catcall
--              if attached (a_type.equal (a_type, l_rel.item.secondary_type)) then -- Catcall because b signature is like a
                if {SIT_UTIL}.class_name_lowercase (a_type).is_equal({SIT_UTIL}.class_name_lowercase (l_rel.item.secondary_type)) then
                    Result := l_rel.item
                end
            end
            check
                not_found_relationship: Result /= Void
            end
        end

1 Ответ

2 голосов
/ 29 июня 2019

Свойство соответствия является антисимметричным, т. Е. Если A → B и B → A , то A = B .Таким образом, два типа равны, если они соответствуют друг другу:

    a_type.conforms_to (l_rel.item.secondary_type) and
    l_rel.item.secondary_type.conforms_to (a_type)

(Хотя conforms_to сравнивает типы объектов, а не сами объекты, приведенное выше выражение все еще в порядке, поскольку из-за правил соответствия A = B тогда и только тогда, когда TYPE [A] = TYPE [B] , когда A и B сами являются типами.)

Если один из типов прикреплен, а другой является съемным, вы все равно можете сравнить их как равные.В этом случае можно использовать следующий код:

    is_conforming (a_type, l_rel.item.secondary_type) and
    is_conforming (l_rel.item.secondary_type, a_type)

, где предикат сравнения игнорирует метку вложения:

is_conforming (t1, t2: TYPE [detachable ANY]): BOOLEAN
  do
    Result :=
      ({REFLECTOR}.type_of_type ({REFLECTOR}.detachable_type (t1.type_id))).conforms_to
      ({REFLECTOR}.type_of_type ({REFLECTOR}.detachable_type (t2.type_id)))
  end
...