Page 1 of 1

Defining Components vs Fields

Posted: Sat Dec 10, 2016 5:15 am
by jyoung
Something I've struggled with for a while now, but what is the difference in using define_com vs define field?

Code: Select all

define_com class(#STD_STRNG) name(#myString)
and

Code: Select all

define field(#myString) type(*STRING)
Sometimes I have to store a list of strings in a collection so I define it like

Code: Select all

define_com class(#PRIM_ACOL<#STD_STRNG>) name(#myCollection)
The only way for me to add a string into the collection is by using the define_com command

Code: Select all

define_com class(#STD_STRNG) name(#myString)
#myString := "Hello"
#myCollection.Insert( #myString )
When I try using define or just STD_STRNG

Code: Select all

define field(#myString) type(*STRING)
#myString := "Hello"
#myCollection.Insert( #myString )
or

Code: Select all

#STD_STRNG := "Hello"
#myCollection.Insert( #STD_STRNG )
I get a "#STD_STRNG is not a component" error.

Re: Defining Components vs Fields

Posted: Sat Dec 10, 2016 9:25 am
by Stewart Marshall
Hi Joe

OK...here goes...hope this helps.

Code: Select all

define field(#myString) type(*STRING)
This is a simple variable and is exactly the same as a field in the repository. It exists within the component in which it's used and its value can be passed to other components, resulting in multiple copies of the value.

Code: Select all

define_com class(#STD_STRNG) name(#myString)
This is a component instance, so it obeys the rules of components. If you put the define_com inside a method, the component will come alive for the duration of the method and then be destroyed. If you pass it between methods and components *By_reference, there will only ever be one instance of it.

Code: Select all

define_com class(#PRIM_ACOL<#STD_STRNG>) name(#myCollection)
Collections collect component instances. This one collects components of class Std_string. This means you have a collection of components that store alphanumeric data up to 512 long.

To populate the collection, you need to create new instances of the std_string component, something you're doing currently with the Define_com. You can also do the following

Code: Select all

#myCollection.insert((*New #std_strng))
#Mycollection.last := "Hello"
This works because the objects are component instances and can be accessed as and when.

However, in this last example...

Code: Select all

#STD_STRNG := "Hello"
#myCollection.Insert( #STD_STRNG )
... #std_string is most definitely NOT a component instance. It's just a simple variable value like #myString.

This is not entirely obvious and using the same name for 2 different jobs can be a touch confusing as you've discovered.

To ensure a little more clarity, try using #Prim_alph or #Prim_dc.Unicode for collections of strings. These are basic primitive alphanumeric and Unicode classes

Code: Select all

define_com class(#PRIM_ACOL<#Prim_dc.Unicode>) name(#myCollection)

Code: Select all

#myCollection.insert((*New #Prim_dc.Unicode))
#Mycollection.last := "Hello"