Defining Components vs Fields

This Q&A forum allows users to post and respond to "How Do I Do ....." questions. Please do not use to report (suspected) errors - you must use your regional help desk for this. The information contained in this forum has not been validated by LANSA and, as such, LANSA cannot guarantee the accuracy of the information.
Post Reply
jyoung
Posts: 694
Joined: Thu Jan 21, 2016 6:43 am
Location: Oklahoma City, OK USA

Defining Components vs Fields

Post 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.
User avatar
Stewart Marshall
Posts: 417
Joined: Thu Nov 05, 2015 5:25 pm

Re: Defining Components vs Fields

Post 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"
Stewart Marshall

Independent IT Consultant
www.marshallfloyd.com.au
Post Reply