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: adeas31
Priority: critical Milestone:
Component: OMEdit Version: v.1.15.0-dev
Keywords: Cc: adrpo

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)

Changed 4 years ago by timswait@…

package containing frame_model and control_frame

Changed 4 years ago by timswait@…

demo file showing control_frame works fine by itself.

comment:1 Changed 4 years ago by timswait@…

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 follow-up: Changed 4 years ago by anonymous

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.

comment:3 in reply to: ↑ 2 Changed 4 years ago by casella

  • Resolution set to invalid
  • Status changed from new to closed

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 follow-up: Changed 4 years ago by 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.

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!)

Changed 4 years ago by timswait@…

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

comment:5 Changed 4 years ago by timswait@…

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)));

comment:6 in reply to: ↑ 4 ; follow-up: Changed 4 years ago by casella

  • Component changed from *unknown* to OMEdit
  • Milestone changed from Future to 1.17.0
  • Resolution invalid deleted
  • Status changed from closed to reopened

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 Changed 4 years ago by casella

  • Cc adrpo added
  • Owner changed from somebody to adeas31
  • Status changed from reopened to assigned

comment:8 in reply to: ↑ 6 ; follow-up: Changed 4 years ago by timswait@…

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?

comment:9 in reply to: ↑ 8 Changed 4 years ago by casella

  • Priority changed from high to critical

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 Changed 4 years ago by casella

  • Milestone changed from 1.17.0 to 1.18.0

Retargeted to 1.18.0 because of 1.17.0 timed release.

comment:11 Changed 3 years ago by casella

  • Milestone 1.18.0 deleted

Ticket retargeted after milestone closed

Note: See TracTickets for help on using tickets.