OOP Question: accessing object values from a class?

Hi all,

just getting started in graphics (never had a need before) and am making good progress, but I’ve run into a situation a few times which puzzles me.

I analyse some text files, extract lists of drawable objects (a custom class “cfragments”) from them, and display those on a custom canvas (“cCanProteinPrint”)
[the c prefix is for class]

The custom canvas has a property DictModificationsIdentified as Dictionary that stores information extracted from the text files that is needed to draw the fragments. So it is basically a lookup table.

DictModificationsIdentified is initiated in the constructor of the class, so is available.

I can extract the required info from the text and put it into DictModificationsIdentified.

But I can’t access the DictModificationsIdentified from the fragments.

In the Paint event of cfragment I have

cCanProteinPrint.DictModificationsIdentified.value( somekey ) = somevalue

but get a “this item or method does not exist” on DictModificationsIdentified

I can work around this by adding an additional DictModificationsIdentified as dictionary to the cfragments class and setting it to the same as the one in cCanProteinPrint (in the Open event of the canvas)

But why? As far as I can see the code should work, so there is clearly something amiss in my OOP understanding.

Can anyone explain where I’m going wrong?

Thanks

Markus

P.S.

So does your cCanProteinPrint have a public property DictModificationsIdentified and then in your constructor you have

 DictModificationsIdentified = new Dictionary

then you should be able to access it by cCanProteinPrint.DictModificationsIdentified.value( somekey ) = somevalue

[quote=117883:@Markus Winter]In the Paint event of cfragment I have

cCanProteinPrint.DictModificationsIdentified.value( somekey ) = somevalue
but get a “this item or method does not exist” on DictModificationsIdentified

I can work around this by adding an additional DictModificationsIdentified as dictionary to the cfragments class and setting it to the same as the one in cCanProteinPrint (in the Open event of the canvas)[/quote]

My first thought was that you didn’t have DictModificationsIdentified set as a public value. But then you mention that you can set it within the Open event, so I’m not sure that’s it.

I’m still a little vague on the relationship between the two classes, though (cfragments and cCanProteinPrint). But if you’re directly accessing the dictionary property of cCanProteinPrint, then it should work, unless it’s not set as public.

Are you sure the error you’re getting is about cCanProteinPrint. DictModificationsIdentified? The error could be about something else on the same line.

Yes I am too, but just set this up and I can access cCanProteinPrint.DictModificationsIdentified in the open event of a window.

I i’m not 100% sure what you meant but I think I know so I tried this. In cFragment I put a method :

Sub GetModicfication(modsIdented as Dictionary) MsgBox modsIdented.Value("test") End Sub

Then when you have initiated your cFragment, call GetModicfication as follows:

[code] dim myFrag as new cfragment

cCanProteinPrint1.dictModificationsIdentified.Value(“test”) = “a new value”

myFrag.GetModicfication(cCanProteinPrint1.dictModificationsIdentified)[/code]

Run it and you will get a msgbox from your fragment saying test which has come from your cCanProteinPrint1.dictModificationsIdentified

Here, the demo I tried out Demo

[quote=117886:@Mike Charlesworth]So does your cCanProteinPrint have a public property DictModificationsIdentified and then in your constructor you have

 DictModificationsIdentified = new Dictionary

then you should be able to access it by cCanProteinPrint.DictModificationsIdentified.value( somekey ) = somevalue[/quote]

Yes it has. And yes, I do.

That’s why I do not understand this at all.

Hi Marc, the whole thing is actually build on your SuperDraw design from REALbasic University days :wink:

cCanProteinPrint has an ObjectList as cDrawableObject
It has several LookupTables for values (like which position has which modification) implemented as dictionaries

cFragment is a subclass of cDrawableObject

For the workaround I add another dict to the cDrawableObject.

[code] // this doesn’t work:

for each key as variant in cCanvasProteinPrint.DictModificationAtPosition.Keys

next

// this workaround works:

for each key as variant in me.DictModificationAtPosition.Keys

next[/code]

P.S. Same thing using either RS2012R2.1 or Xojo 2014R2

Btw the autocomplete works fine with it.

[quote=117896:@Markus Winter]cCanProteinPrint has an ObjectList as cDrawableObject
It has several LookupTables for values (like which position has which modification) implemented as dictionaries

cFragment is a subclass of cDrawableObject[/quote]
Maybe you have only to do a cast

From what you say:
ObjectList isA cDrawableObject
cFragment has an DictModificationsIdentified property but cDrawableObject (the cFragment superclass) has no info about this property

I made a simple demo (sorry, should have done that immediately. Noted for future reference) which shows the error:

https://dl.dropboxusercontent.com/u/992591/REALbasic/Forum/Class%20Error.rbp.zip

Try this https://www.cubbyusercontent.com/pli/mwinters%20Class%20Error.rbp/_9ddf173f71814de7bc597bfbd6e6d53d

See I have added the host property to your cFragment which is set in your cFragment constructor and is a reference to your initiated cCanProteinPrint and then in your paint event you can reference host with no errors:

[code] for each key as variant in host.DictMods.Keys

next[/code]

Thanks for the demo. But it’s again a workaround, you simply pass the dictionary into the class by using a method. Unfortunately that won’t work for me as I need the code in the paint event.

Which is pretty much what my workaround does too: you add the canvas as reference, I add the canvas’ dictionary as reference.

So there are workarounds, but the initial question remains: why can’t you access the object from a class? (see my example project)

Or in other words: what is the actual problem? A bug? Or my OOP design understanding (quite likely)?

From the cFragment point of view… who is cCanProteinPrint?
you are accessing this property like a shared property, but you have defined it as an instance property.

[quote=117909:@Antonio Rinaldi]From the cFragment point of view… who is cCanProteinPrint?
you are accessing this property like a shared property, but you have defined it as an instance property.[/quote]

cCanProteinPrint is another custom class in the project.

I do not understand the second line. Please elaborate.

[quote=117909:@Antonio Rinaldi]From the cFragment point of view… who is cCanProteinPrint?
you are accessing this property like a shared property, but you have defined it as an instance property.[/quote]

Exactly which is why you need to tell the cFragment who has the DictMods property in the way I have done it in the cFragment constructor

According to the class error demo there is no instance of cCanProteinPrint. There is a control in Window1 called CanProteinPrint which has a super of Canvas. I can make the problem go away by changing this control’s super to cCanProteinPrint and referencing that control in the Paint event of cFragment.

  for each key as variant in Window1.CanProteinPrint.DictMods.Keys
    
  next
  

Don’t know if that’s just an oversight in the cut down version.

[quote=117914:@Wayne Golding]According to the class error demo there is no instance of cCanProteinPrint. There is a control in Window1 called CanProteinPrint which has a super of Canvas. I can make the problem go away by changing this control’s super to cCanProteinPrint and referencing that control in the Paint event of cFragment.

  for each key as variant in Window1.CanProteinPrint.DictMods.Keys
    
  next
  

Don’t know if that’s just an oversight in the cut down version.[/quote]
But Wayne, Is this not bad OOP design from a reusability pout of view. You are referencing an instance (Window1.CanProteinPrint) in your class (cFragment) directly. Which is why I opted for passing cFragment the instance of the CanProteinPrint in its constructor.

Sorry, yes, it was.

Which is what I’m trying to avoid.

What I don’t get:

I have modules and classes and can reference their properties from other classes just fine.

I can have object properties in modules and can reference them fine.

However if I have a class with an object property then it seems I can’t.

P.S. If I put the DictMod into a module then accessing it is not a problem.