Opened 4 years ago

Last modified 3 years ago

#6000 assigned defect

Expected "XXX" to be a class, but found component instead.

Reported by: timswait@… Owned by: Adeel Asghar
Priority: critical Milestone:
Component: OMEdit Version: v.1.15.0-dev
Keywords: Cc: Adrian Pop

Description

I keep coming across an error of a form "Expected 'XXX' to be a class, but found component instead." when I try to insert a model into another model and I can't work out what is causing it. It seems to happen sporadically and I can't really work out what is causing it.

Most recently I was working on the attached "frame_model_pack" This contains "frame_model" which references two other models "keel" and "control_frame". This was working fine, then I made some minor adjustments to "control_frame" (changing the icon and tweaking some initial conditions) and now I get this error:

[1] 13:52:42 Translation Error
[frame_model_pack: 16:3-17:117]: Expected control_frame to be a class, but found component instead.

Unfortunately I saved the model and re-opened OMEdit so I can't simply undo back to the working state! I simply don't understand why it went from working to not working like this. If I reference "control_frame" in another model outside of "frame_model_pack" then it does still work. Also 'keel' is inside "frame_model_pack" and that has no problem being referenced by "frame_model", so it's not that you can't reference a model from within the same package (and as I say, this was working until I made some minor tweaks to control_frame).

Attachments (3)

frame_model_pack.mo (12.3 KB ) - added by timswait@… 4 years ago.
package containing frame_model and control_frame
scratch.mo (727 bytes ) - added by timswait@… 4 years ago.
demo file showing control_frame works fine by itself.
frame_model_pack.2.mo (13.2 KB ) - added by timswait@… 4 years ago.
frame model with capitalised classes still showing difference of treatment of keel and control frame.

Download all attachments as: .zip

Change History (14)

by timswait@…, 4 years ago

Attachment: frame_model_pack.mo added

package containing frame_model and control_frame

by timswait@…, 4 years ago

Attachment: scratch.mo added

demo file showing control_frame works fine by itself.

comment:1 by timswait@…, 4 years ago

Looking into the Modelica code I can see that the keel (which works) is defined as:

frame_model_pack.keel keel

but the control frame (which doesn't) is defined as:

control_frame control_frame

If I manually edit in "frame_model_pack." in front of control_frame then it's happy. Alternatively if I change the name of the control_frame instance to something else then it's happy, so the problem appears to be that I have an instance and a class with the same name and when it's not given the class the full address then it's not happy (I might not be using the correct technical coding terms here, I'm just an engineer!).

However I effectively did the same thing, dragging and dropping 'keel' from the left side bar tree onto my block diagram, not bothering to change from the default instance name of 'keel', then dragging and dropping 'control_frame' from the left side bar onto my block diagram and not bothering to change from the default instance name of 'control_frame'. For some reason with keel, OMEdit references it fully as 'frame_model_pack.keel' and for control_frame it doesn't.

comment:2 by anonymous, 4 years ago

It's not good to use the same name for classes and instances.
I propose you to use the standard Modelica convention (Modelica.UsersGuide.Conventions.ModelicaCode.Naming) requiring classes to start with an uppercase letter, instances with a lowercase.
If I understand well your description, this, in addition to making your code much cleaner, should solve your problem.

in reply to:  2 comment:3 by Francesco Casella, 4 years ago

Resolution: invalid
Status: newclosed

Replying to anonymous:

It's not good to use the same name for classes and instances.

I'd say it's plain wrong, though I can't point you the exact place in the specification where this is stated. Maybe someone else can.

I propose you to use the standard Modelica convention (Modelica.UsersGuide.Conventions.ModelicaCode.Naming) requiring classes to start with an uppercase letter, instances with a lowercase.

I also recommend to follow this practice. The only exception among class names is function names, because functions are never instantiated but only called within expressions.

comment:4 by timswait@…, 4 years ago

Thanks for the replies. I will now follow this naming convention on capitalising classes as I can see that it will solve this problem. However, coming as someone with very little coding experience (some dabbling in Python where I've never come across this issue) it's not obvious what's going on.

Also as the default behaviour of OMEdit is to give the first instance on a block diagram the same name as the class (in lower case) then if you haven't capitalised the class name then it will often (but even more confusingly not always!) run into this problem.

There is some inconsistency somewhere in how it behaves when you drag and drop across from the left bar to the block diagram, I can't work out why this is. I've now edited my model to have capitals on the class names, deleted keel (now Keel) instances and control_frame (now Control_Frame) from frame_model (now Frame_Model) however when I drag them back onto the block diagram you can see in the code that for some reason Keel is fully referenced and Control_Frame is not:

frame_model_pack.Keel keel annotation(
    Placement(visible = true, transformation(origin = {-56, 10}, extent = {{-50, -10}, {50, 10}}, rotation = 0)));
frame_model_pack.Keel keel1 annotation(
    Placement(visible = true, transformation(origin = {-28, 74}, extent = {{-50, -10}, {50, 10}}, rotation = 0)));
Control_Frame control_Frame annotation(
    Placement(visible = true, transformation(origin = {-34, -48}, extent = {{-20, -20}, {20, 20}}, rotation = 0)));

So my suggestions would be:
-Could there be a warning when you try to create an instance with the same name as a class?
-Could there at least be consistency of behaviour when you drag and drop from the left menu onto the block diagram so it either fully references the class as it's done for Keel (which as I understand will make things work even though it's poor practice) or it always doesn't fully reference as it's done for Control_Frame (which will make it always not work which at least makes the debugging easier and forces good practice!)

by timswait@…, 4 years ago

Attachment: frame_model_pack.2.mo added

frame model with capitalised classes still showing difference of treatment of keel and control frame.

comment:5 by timswait@…, 4 years ago

I thought maybe it had something to do with the number of instances, but it's not that, adding a second Control_Frame it still isn't fully referenced, but adding a third Keel it is fully referenced:

frame_model_pack.Keel keel annotation(
    Placement(visible = true, transformation(origin = {-56, 10}, extent = {{-50, -10}, {50, 10}}, rotation = 0)));
frame_model_pack.Keel keel1 annotation(
    Placement(visible = true, transformation(origin = {-28, 74}, extent = {{-50, -10}, {50, 10}}, rotation = 0)));
Control_Frame control_Frame annotation(
    Placement(visible = true, transformation(origin = {-34, -48}, extent = {{-20, -20}, {20, 20}}, rotation = 0)));
Control_Frame control_Frame1 annotation(
    Placement(visible = true, transformation(origin = {102, -40}, extent = {{-20, -20}, {20, 20}}, rotation = 0)));
frame_model_pack.Keel keel2 annotation(
    Placement(visible = true, transformation(origin = {-24, -84}, extent = {{-50, -10}, {50, 10}}, rotation = 0)));

in reply to:  4 ; comment:6 by Francesco Casella, 4 years ago

Component: *unknown*OMEdit
Milestone: Future1.17.0
Resolution: invalid
Status: closedreopened

Replying to timswait@…:

Thanks for the replies. I will now follow this naming convention on capitalising classes as I can see that it will solve this problem. However, coming as someone with very little coding experience (some dabbling in Python where I've never come across this issue) it's not obvious what's going on.

In hindsight, if you define an object control_frame of type control_frame, the compiler error: "Expected control_frame to be a class, but found component instead" should be quite clear. But it's probably not, if you lack experience. Maybe could you suggest a more explanatory error message?

Also as the default behaviour of OMEdit is to give the first instance on a block diagram the same name as the class (in lower case) then if you haven't capitalised the class name then it will often (but even more confusingly not always!) run into this problem.

I agree that OMEdit shouldn't do that.

So my suggestions would be:
-Could there be a warning when you try to create an instance with the same name as a class?

Sure. In fact, I would suggest that OMEdit should refuse to create an instance with the same name as the class and issue an error message suggesting to change the class name to uppercase, if possible, or otherwise to use some other name for the instance.

-Could there at least be consistency of behaviour when you drag and drop from the left menu onto the block diagram so it either fully references the class as it's done for Keel (which as I understand will make things work even though it's poor practice) or it always doesn't fully reference as it's done for Control_Frame (which will make it always not work which at least makes the debugging easier and forces good practice!)

I guess this is a resonable request, I don't know why this happens. Maybe related to similar issues we have when duplicating class definitions.

@adeas31, @adrpo, is this an API issue or an OMEdit issue?

comment:7 by Francesco Casella, 4 years ago

Cc: Adrian Pop added
Owner: changed from somebody to Adeel Asghar
Status: reopenedassigned

in reply to:  6 ; comment:8 by timswait@…, 4 years ago

Replying to casella:

Thank you for being so helpful and giving time and attention to my troubles!

Replying to timswait@…:

Thanks for the replies. I will now follow this naming convention on capitalising classes as I can see that it will solve this problem. However, coming as someone with very little coding experience (some dabbling in Python where I've never come across this issue) it's not obvious what's going on.

In hindsight, if you define an object control_frame of type control_frame, the compiler error: "Expected control_frame to be a class, but found component instead" should be quite clear. But it's probably not, if you lack experience. Maybe could you suggest a more explanatory error message?

Yes, I agree in hindsight now it seems obvious, but at the the time it was very infuriating, lots of swearing at the computer along the lines of "control_frame is a class! I know it's a damn class, I clicked the 'New Class' button to create it so why are you telling me it's a component?!" :-) When you're new to coding the distinction between terms like classes, components and instances isn't obvious. This ended up causing hours of frustration. It also led me into the false belief that I could only import other models as blocks if they were themselves in packages (as that seemed to avoid that error message for a while).

However, I don't think there's any need to change the compiler error code, I agree that's clear enough when you know what it means. I think the most important change would be to change the behaviour of OMEdit to prevent this happening (or at least make it much harder). It already prevents you adding two components to a block diagram with the same name, so I would have thought it wouldn't be too hard to make it prevent you adding a component with the same name as a class?

in reply to:  8 comment:9 by Francesco Casella, 4 years ago

Priority: highcritical

Replying to timswait@…:

Yes, I agree in hindsight now it seems obvious, but at the the time it was very infuriating, lots of swearing at the computer along the lines of "control_frame is a class! I know it's a damn class, I clicked the 'New Class' button to create it so why are you telling me it's a component?!" :-)

The compiler is always right. Except, of course, when it isn't :)

I would have thought it wouldn't be too hard to make it prevent you adding a component with the same name as a class?

Absolutely! We'll take care of that ASAP

comment:10 by Francesco Casella, 4 years ago

Milestone: 1.17.01.18.0

Retargeted to 1.18.0 because of 1.17.0 timed release.

comment:11 by Francesco Casella, 3 years ago

Milestone: 1.18.0

Ticket retargeted after milestone closed

Note: See TracTickets for help on using tickets.