Search code examples
eiffel

Eiffel: type casting operators whats the difference between ~ / and attached statements?


Whats the difference between

  • object test

    if attached {DOG} an_animal as a_dog then
       a_dog.eat (meat)
    end
    
  • operator / of the class TYPE

    if an_animal / a_dog then
       an_animal.eat (food)
    end
    
  • reference equality =

    if a_dog = an_animal then
        a_dog.eat (meat)
    else
        an_animal.eat (food) 
    end
    
  • object equality ~

    if a_dog ~ an_animal then
        a_dog.eat (meat)
    else
        an_animal.eat (food) 
    end
    

And where can I find documentation about that?


Solution

  • The main differences among the constructs are in operand types and semantics.

    1. An object test allows for figuring out whether a particular expression evaluates to a value conforming to a particular type. The value of the conforming object can be retrieved via an associated object test local.

    2. The operator / of the class TYPE returns the value of the passed argument, if it conforms to the type specified by the type object. Otherwise, it returns Void for a reference type and a default value for an expanded type. This is quite similar to object test, but has minor differences. Essentially, the expression {SOME_TYPE} / expression is equivalent to

      if attached {SOME_TYPE} expression as value then
          value
      else
          {detachable SOME_TYPE}.default
      end
      

      For reference types, the object test attached {SOME_TYPE} expression as value is equivalent to

      attached ({SOME_TYPE} / expression) as value
      

      But there is no equivalent for expanded types.

      The main use of the operator / is to obtain a value of a specific type if possible or Void otherwise:

      x := {SOME_TYPE} / expression
      
    3. Reference equality = compares (most of the time) object references and has nothing to do with their types. In other words, a = b for reference objects means that a and b are aliases. If one of the operands is an expanded object, = is the same as object equality (see below).

      If the expression dog = animal returns True, the variables dog and animal reference the same object, but we have no idea what type it is.

    4. Object equality ~ compares contents of two objects. First, it checks that both are non-void, have the same type, and then invokes a (user-defined) predicate is_equal to get the result of the operator.

      If the expression dog ~ animal returns True, the variables dog and animal could be the same or different objects that have the same type and are equal (according to is_equal). As in the previous case, we have no idea what type they are.

    1, 3 and 4 are documented in the language standard, 2 is a feature of the class TYPE (with the corresponding name attempted).