0

I know how to fix it (see my solution @bottom) but don't understand why this compilation error occurs, as in my mind, renamed attributes should be created by the Precursor into default_create. Why isn't that so?

NRJ_ENTITY

inherit
    ANY
        redefine
            default_create
        end

feature {NONE} -- Initialization

    default_create
        do
            create current_day
            create current_month
            create current_year
            Precursor
        end

feature -- Access

    current_day,
    current_month,
    current_year: ENERGY_UNIT

end

NRJ_CONSUMER

inherit
    NRJ_ENTITY

end

NRJ_GENERATOR

inherit
    NRJ_ENTITY

end

NRJ_GENERATOR_CONSUMER

inherit
    NRJ_GENERATOR
        rename
            current_day as current_day_generation,
            current_month as current_month_generation,
            current_year as current_year_generation
        redefine
            default_create
        select
            current_day_generation,
            current_month_generation,
            current_year_generation
        end
    NRJ_CONSUMER
        rename
            current_day as current_day_consumption,
            current_month as current_month_consumption,
            current_year as current_year_consumption
        redefine
            default_create
        end

feature {NONE} -- Initialize

    default_create
        do
            Precursor {NRJ_GENERATOR}
            Precursor {NRJ_CONSUMER}
        end

end

Error screenshot

enter image description here

Fix into NRJ_GENERATOR_CONSUMER

default_create
    do
        create current_day_consumption
        create current_month_consumption
        create current_year_consumption
        Precursor {NRJ_CONSUMER}
        Precursor {NRJ_GENERATOR}
    end
Alexander Kogtenkov
  • 5,770
  • 1
  • 27
  • 35
Pipo
  • 4,653
  • 38
  • 47

1 Answers1

1

Class NRJ_GENERATOR_CONSUMER has two versions of every attribute from NRJ_ENTITY. For example, current_day has versions current_day_generation and current_day_consumption. The code in NRJ_ENTITY works only with one version of current_day, possibly renamed. It has no idea about the second version. In order to tell which version of the replicated attribute (or a feature, in general) should be used, the class with the replication should select exactly one suitable version.

In the example, the selected version is current_day_generation. Therefore, default_create inherited from NRJ_ENTITY initializes it and not the other attribute. In other words, with replication,

create current_day

is not automatically translated into

create current_day_generation
create current_day_consumption

but just into

create current_day_generation -- The selected version.

This explains why you need the fix you are referring to.

Also, note that the instructions Precursor {NRJ_CONSUMER} and Precursor {NRJ_GENERATOR} call exactly the same version of default_create defined in NRJ_ENTITY, so one of the calls can be safely removed.

Summary: Inherited code deals only with selected versions of replicated features.

Corollary: Non-selected versions of replicated attributes have to be explicitly initialized in the class where they are replicated.

Alexander Kogtenkov
  • 5,770
  • 1
  • 27
  • 35
  • Many thx, should't be a best practice to keep both `Precursor` calls in case a redfinition is made into one of the parents? – Pipo Dec 29 '19 at 13:29
  • 1
    @Pipo It depends on the application. For example, if the creation procedure opens a file, it might be problematic to call the procedure twice. – Alexander Kogtenkov Dec 29 '19 at 14:06