Method options *CONSTRUCTOR and *REQUIRED

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
User avatar
MarcusLancaster
Posts: 24
Joined: Tue Nov 24, 2015 9:20 pm

Method options *CONSTRUCTOR and *REQUIRED

Post by MarcusLancaster » Thu Nov 28, 2019 4:15 am

Hi all.

Has anybody got an example which demonstrates why you would use the *REQUIRED option on a method? I've got a *CONSTRUCTOR method running... but can't see why I would need to include *REQUIRED... the documentation simply states;

"In conjunction with *Constructor. *REQUIRED specifies that a constructor method must be invoked"

I've tried to contrive a situation where a second Constructor is defined with *REQUIRED, but where I deliberately do not cause it to run... but it doesn't appear to fail or error etc... and as far as I understand it, if there is only one Constructor, then it would run anyway...

Just wondered where / why I would use it?

Cheers for now.

Marcus.

BrendanB
Posts: 35
Joined: Tue Nov 24, 2015 10:29 am

Re: Method options *CONSTRUCTOR and *REQUIRED

Post by BrendanB » Fri Nov 29, 2019 9:51 am

Marcus,

try creating a RP

Code: Select all


Function Options(*DIRECT)
Begin_Com Role(*EXTENDS #PRIM_OBJT)

Define_Com Class(#prim_alph) Name(#searchValue)
Define_Com Class(#prim_alph) Name(#replacementValue)

Define_Pty Name(SearchValue) Get(*Auto #searchValue) Set(*Auto #searchValue)
Define_Pty Name(ReplacementValue) Get(*Auto #replacementValue) Set(*Auto #replacementValue)

Mthroutine Name(Create) Options(*CONSTRUCTOR *REQUIRED)
Define_Map For(*INPUT) Class(#prim_alph) Name(#Key)
Define_Map For(*INPUT) Class(#prim_alph) Name(#Value)

#searchValue := #Key
#replacementValue := #Value

Endroutine

End_Com

and then try and use it like:

Code: Select all

Define_com class(#PRIM_LCOL<#SimpleClass>) name(#ClassList)

mthroutine Name(DoSomething)

#ClassList.RemoveAll

#ClassList.Insert( (*New #SimpleClass.Create('a' 'value')))
#ClassList.Insert((*New #SimpleClass))   // should fail here

endroutine

This is a contrived example, but you should get an error message when you try and *NOT* use a constructor.

User avatar
MarcusLancaster
Posts: 24
Joined: Tue Nov 24, 2015 9:20 pm

Re: Method options *CONSTRUCTOR and *REQUIRED

Post by MarcusLancaster » Sat Nov 30, 2019 2:46 am

Hey Brendan!

Thanks for your code sample - I think the problem I had was that my assumption was that the *REQUIRED parm was related to the method, but it seems to be more related to the define_map(s). In all my tests, to keep it simple, I didn't have any define_maps.

As you indicate, if you include a DEFINE_MAP parm in the Constructor method;

Code: Select all

mthroutine umConstructor options(*CONSTRUCTOR *REQUIRED)
define_map for(*input) class(#std_text) name(#iText)
#sys_web.alert caption('Running Constructor method')
endroutine
but then DON'T specify a parm value where the component is instantiated;

Code: Select all

#ACOL_Test.Insert((*NEW #TestComponent))

you do get an error...

An instance of class name <component class> can only be created by calling the constructor marked *REQUIRED

But the message is misleading - its the missing parm which seems to be the issue, rather than the lack of a constructor. If you remove the DEFINE_MAP from the component, the syntax is good, because the *NEW syntax will find the constructor. So *REQUIRED would appear to be more about the requirement to include parms when instantiating a component... maybe the message needs changing?

Anyway - thanks again for the code, that's the clue I needed!! At least I'm getting the message now!! Much appreciated!

Cheers for now.

Marcus.

BrendanB
Posts: 35
Joined: Tue Nov 24, 2015 10:29 am

Re: Method options *CONSTRUCTOR and *REQUIRED

Post by BrendanB » Mon Dec 02, 2019 9:42 am

Marcus,

The thing to remember:

*New #TestComponent

is not the same as

*New #TestComponent.umConstructor

The first is the *DEFAULT* constructor, the second is the constructor that you defined.

The required flag tells VL that it cannot use the default constructor for the object.

I think the bug is that the constructor you have written should force you to declare *New #TestComponent.umConstructor

Post Reply