For Programmers: Free Programming Magazines  


Home > Archive > Cobol > March 2006 > Re: Java compatibility issues (WAS: MF having issues?)









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author Re: Java compatibility issues (WAS: MF having issues?)
James J. Gavan

2006-03-08, 3:55 am

Frank Swarbrick wrote:

Do about 12 Page Downs to get to my comments, finishing with a question
on Components for PECD :-

> Oliver Wong<owong@castortech.com> 03/06/06 8:24 AM >>>
>
>
>
> Could be. I "learned" OO with C++, which also doesn't have the "factory"
> descriptor, so I had never heard of it. And the books I read (err, skimmed)
> on OO-COBOL didn't do a very good job explaining it. Of course I don't
> recall
> I just did a Google search on "OO COBOL FACTORY" and found the following in
> the docs for COBOL for AIX:
> "COBOL factory methods are equivalent to public static methods in Java" and
> "COBOL factory data is equivalent to private static data in Java"
> Interesting!
> One other thing I find confusing about COBOL factories is the position of
> the keyword within the code. I would like it to be nearer to the, umm,
> object that is a factory. Here's an example from that same manual (how it
> actually is):
>
> ----------------------------------------------------------------------------
> ----------
> Identification Division.
> Class-id. Account inherits Base.
> Environment Division.
> Configuration section.
> Repository.
> Class Base is "java.lang.Object"
> Class Account is "Account".
> *
> Identification division.
> Factory.
> Data division.
> Working-storage section.
> 01 NumberOfAccounts pic 9(6) value zero.
> *
> Procedure Division.
> *
> * createAccount method to create a new Account
> * instance, then invoke the OBJECT paragraph's init
> * method on the instance to initialize its instance data:
> Identification Division.
> Method-id. "createAccount".
> Data division.
> Linkage section.
> 01 inAccountNumber pic S9(6) binary.
> 01 outAccount object reference Account.
> * Facilitate access to JNI services:
> Copy JNI.
> Procedure Division using by value inAccountNumber
> returning outAccount.
> * Establish addressability to JNI environment structure:
> Set address of JNIEnv to JNIEnvPtr
> Set address of JNINativeInterface to JNIEnv
> Invoke Account New returning outAccount
> Invoke outAccount "init" using by value inAccountNumber
> Add 1 to NumberOfAccounts.
> End method "createAccount".
> *
> End Factory.
> *
> Identification division.
> Object.
> Data division.
> Working-storage section.
> 01 AccountNumber pic 9(6).
> 01 AccountBalance pic S9(9) value zero.
> *
> Procedure Division.
> *
> * init method to initialize the account:
> Identification Division.
> Method-id. "init".
> Data division.
> Linkage section.
> 01 inAccountNumber pic S9(9) binary.
> Procedure Division using by value inAccountNumber.
> Move inAccountNumber to AccountNumber.
> End method "init".
> *
> * getBalance method to return the account balance:
> Identification Division.
> Method-id. "getBalance".
> Data division.
> Linkage section.
> 01 outBalance pic S9(9) binary.
> Procedure Division returning outBalance.
> Move AccountBalance to outBalance.
> End method "getBalance".
> *
> * credit method to deposit to the account:
> Identification Division.
> Method-id. "credit".
> Data division.
> Linkage section.
> 01 inCredit pic S9(9) binary.
> Procedure Division using by value inCredit.
> Add inCredit to AccountBalance.
> End method "credit".
> *
> * debit method to withdraw from the account:
> Identification Division.
> Method-id. "debit".
> Data division.
> Linkage section.
> 01 inDebit pic S9(9) binary.
> Procedure Division using by value inDebit.
> Subtract inDebit from AccountBalance.
> End method "debit".
> *
> * print method to display formatted account number and balance:
> Identification Division.
> Method-id. "print".
> Data division.
> Local-storage section.
> 01 PrintableAccountNumber pic ZZZZZZ999999.
> 01 PrintableAccountBalance pic $$$$,$$$,$$9CR.
> Procedure Division.
> Move AccountNumber to PrintableAccountNumber
> Move AccountBalance to PrintableAccountBalance
> Display " Account: " PrintableAccountNumber
> Display " Balance: " PrintableAccountBalance.
> End method "print".
> *
> End Object.
> *
> End class Account.
> ----------------------------------------------------------------------------
> ----------
>
> But I would prefer something like this:
>
> ----------------------------------------------------------------------------
> ----------
> Class-id. Account inherits Base.
> Class Base is "java.lang.Object"
> Class Account is "Account".
>
> 01 NumberOfAccounts pic 9(6) FACTORY value zero.
>
> 01 AccountNumber pic 9(6).
> 01 AccountBalance pic S9(9) value zero.
>
> * createAccount method to create a new Account
> * instance, then invoke the OBJECT paragraph's init
> * method on the instance to initialize its instance data:
>
> Method-id. "createAccount" is FACTORY
> using by value inAccountNumber
> returning outAccount.
> 01 inAccountNumber pic S9(6) binary.
> 01 outAccount object reference Account.
> Copy JNI.
>
> * Establish addressability to JNI environment structure:
> Set address of JNIEnv to JNIEnvPtr
> Set address of JNINativeInterface to JNIEnv
> set outAccount to Account::New
> outAccount::"init" ([value] inAccountNumber)
> Add 1 to NumberOfAccounts.
> End method.
>
> * init method to initialize the account:
> Method-id. "init" using inAccountNumber.
> 01 inAccountNumber pic S9(9) binary.
>
> Move inAccountNumber to AccountNumber.
> End method.
>
> * getBalance method to return the account balance:
> Method-id. "getBalance" returning outBalance.
> 01 outBalance pic S9(9) binary.
>
> Move AccountBalance to outBalance.
> End method.
>
> * credit method to deposit to the account:
> Method-id. "credit" using by value inCredit.
> 01 inCredit pic S9(9) binary.
>
> Add inCredit to AccountBalance.
> End method.
> *
> * debit method to withdraw from the account:
> Method-id. "debit" using by value inDebit.
> 01 inDebit pic S9(9) binary.
>
> Subtract inDebit from AccountBalance.
> End method.
>
> * print method to display formatted account number and balance:
> Method-id. "print".
> 01 PrintableAccountNumber pic ZZZZZZ999999.
> 01 PrintableAccountBalance pic $$$$,$$$,$$9CR.
>
> Move AccountNumber to PrintableAccountNumber
> Move AccountBalance to PrintableAccountBalance
> Display " Account: " PrintableAccountNumber
> Display " Balance: " PrintableAccountBalance.
> End method.
> *
> End class Account.
> ----------------------------------------------------------------------------
>
> I did several things. I eliminiated all of the DIVISIONS. I attached the
> "using" that was specified in the PROCEDURE DIVISION statement and moved it
> to the METHOD-ID statement. I put the FACTORY keyword next to the method or
> data element that it is referring to. And probably a few other things that
> I've already forgotten...
>
> The resulting code is about 50% smaller (in number of lines, anyway). One
> thing I don't have is how to declare "linkage section" items that are not in
> a method's "USING/RETURNING" statement. Ah well...


Not sure that I understood that last bit - are you thinking of how you
store variables related solely to the method - if so, then that's the
method's Local-Storage Section.

Method-id. "doSomething".
*>----------------------
Local-Storage section.
01 ls-TempKounter pic s9(6)v9(05).
Procedure Division.
compute ls-TempKounter = GlobalKounter1 * 2
compute GlobalKounter2 = ls-TempKounter * 6
End Method "doSomething".
*>---------------------------

The two GlobalKounters are in Working-Storage.

Above using 'ignore red tape' could be written in M/F as :-

Method-id. "doSomething".
01 ls-TempKounter pic s9(6)v9(05).
compute ls-TempKounter = GlobalKounter * 2
compute GlobalKounter2 = ls-TempKounter * 6
End Method "doSomething".


Your revision certainly has appeal to me. Just using the Micro Focus
feature 'ignore red tape' I left out lines where the compiler can
currently automatically recognize what's coming up next. Your revised
source was roughly 69 lines, mine below some 87 lines.

There's no way this will compile in Net Express V 3.1 - Most of it would
compile in V 4.0 onwards, although it would hiccup at your copyfile
entries. Not having the V 4 compiler it *might* accept some of your
references to Java. Here's your example modified to leave out the red
tape junk. (I'll leave the comment lines in, just so I don't cheat )

*>---------------------------------------------------------------
Class-id. Account inherits Base.

Repository.
Class Base is "java.lang.Object"
Class Account is "Account".
*
Factory.
Working-storage section.
01 NumberOfAccounts pic 9(6) value zero.
*
* createAccount method to create a new Account
* instance, then invoke the OBJECT paragraph's init
* method on the instance to initialize its instance data:
Method-id. "createAccount".
Linkage section.
01 inAccountNumber pic S9(6) binary.
01 outAccount object reference Account.
* Facilitate access to JNI services:
Copy JNI.
Procedure Division using by value inAccountNumber
returning outAccount.
* Establish addressability to JNI environment structure:
Set address of JNIEnv to JNIEnvPtr
Set address of JNINativeInterface to JNIEnv
Invoke Account New returning outAccount
Invoke outAccount "init" using by value inAccountNumber
Add 1 to NumberOfAccounts.
End method "createAccount".
*
End Factory.
*
Object.
Working-storage section.
01 AccountNumber pic 9(6).
01 AccountBalance pic S9(9) value zero.
*
* init method to initialize the account:
Method-id. "init".
Linkage section.
01 inAccountNumber pic S9(9) binary.
Procedure Division using by value inAccountNumber.
Move inAccountNumber to AccountNumber.
End method "init".
*
* getBalance method to return the account balance:
Method-id. "getBalance".
Linkage section.
01 outBalance pic S9(9) binary.
Procedure Division returning outBalance.
Move AccountBalance to outBalance.
End method "getBalance".
*
* credit method to deposit to the account:
Method-id. "credit".
Linkage section.
01 inCredit pic S9(9) binary.
Procedure Division using by value inCredit.
Add inCredit to AccountBalance.
End method "credit".
*
* debit method to withdraw from the account:
Method-id. "debit".
Linkage section.
01 inDebit pic S9(9) binary.
Procedure Division using by value inDebit.
Subtract inDebit from AccountBalance.
End method "debit".
*
* print method to display formatted account number and balance:
Method-id. "print".
Data division.
Local-storage section.
01 PrintableAccountNumber pic ZZZZZZ999999.
01 PrintableAccountBalance pic $$$$,$$$,$$9CR.
Procedure Division.
Move AccountNumber to PrintableAccountNumber
Move AccountBalance to PrintableAccountBalance
Display " Account: " PrintableAccountNumber
Display " Balance: " PrintableAccountBalance.
End method "print".
*
End Object.
*
End class Account.
---------------------------------------------------------------

Initially liked your idea of shuffling the Linkage syntax to the
Method-name line - but it really is shuffling. Look at the following,
where having used a class AppHouse(keeping) to create a Cheese Treeview,
it returns values to AppDriver. (Having got back to AppDriver I can
destroy/finalize AppHouse which is no longer required :-

*>-------------------------------------------------------------
Method-id. "begin".
*>------------------------------------------------------------
Local-storage section. *> <---- could have left this out
copy "\copylib\sqlResult.cpy" replacing==(tag)== by ==01 ws==.
01 n pic x(4) comp-5.
Linkage section.
01 lnk-Caller object reference.
01 lnk-MakeAstring object reference.
01 lnk-Parent object reference.
01 lnk-Resource object reference.

01 lnk-Objects.
05 lnk-ChoiceDialog object reference.
05 lnk-DBI occurs MaxLevels object reference.
05 lnk-TvControl object reference.
05 lnk-TvDialog object reference.
05 lnk-TvPopup object reference.

Procedure Division using lnk-Caller
lnk-MakeAstring
lnk-Parent
lnk-Resource
returning lnk-Objects.

*> This class performs initial 'housekeepng' and then
*> passes control back to AppDrive.cbl :-
ETC...........

Now it's not often that you want to move a bunch of stuff like above.
Possibly 90% plus of your methods have only ONE parameter (an object,
pic x or a pic 9). But the above does make it clear what is happening.

STATIC DATA :

Seeing as I think both you, Oliver and Pete (with reference to his
Components), have mentioned it. Went looking in the N/E V 4.0 OO on-line
manual - no reference to static, so didn't help much.

Now take the example you have shown us. My contention is that the
FACTORY method could be in the OBJECT, like so :-

The calling program/class which contains in its Repository :-

Class Account is "Account". then invokes :-

invoke Account "new" returning os-AccountObj
invoke os-AccountObj "createAcccount"
using thisAccountNumber(binary) returning thisAccount(object)

and "createAccount" and the invoked "init" are part and parcel of one
method in the OBJECT Section. Then of course you are incrementing the
NumberOfAccounts.

Real world - we may perhaps statistically want to know the total number
of new Accounts we have opened to-day. Now I'll put my wife behind a
cash register at the Bay (Hudson's Bay Company). Marketing - "Get as
many customers as you can to open a Bay credit card account and we'll
give you a voucher for $5". Want to keep tabs on how many accounts
Eileen has managed to 'sell' ? You need Number of Accounts but in the
the INSTANCE that she is using :-

'z' instances x numberOfAccounts = TotalAccounts at this store

which is a pass-back from the individual instances to the Control
Program when the cash register is shut down. Same I'm sure would apply
with tellers in banks with any promotional schemes you have.

Similarly I can't see your Java code would hiccup if it was part of an
INSTANCE (OBJECT) method as opposed to a FACTORY method. Java is after
all in the example being used to control object creation/destruction.

The nearest I came in relevance to FACTORY from my OO Manual was :-

----------------------------------------------------------------------
Data Inheritance

A factory object inherits all the factory data of its superclass, and an
instance object inherits all the instance data of its superclass. The
inherited data of a subclass includes any data that the superclass
itself inherited from a class higher up the hierarchy. The inherited
object data is initialized when an object is created. The inherited
factory data is allocated independently from the factory data of the
inherited class or classes when the factory of the subclass is created.
A subclass can only access inherited data through the methods it
inherited from the same class. For example, if the class Manager
inherits from the class Employee, and Employee defines the data item:

employeeNumber PIC 999

The Manager class cannot store a value in its inherited employeeNumber
data item by using a statement such as:

move 100 to employeeNumber

Instead it must use a method declared in the Employee class, for example:

invoke self "setEmployeeNumber" using 100

The object reference SELF is a reserved name which always refers to the
object in which it occurs (see the section ....
-------------------------------------------------------------------------
The Factory Object Source Element

The factory object source element defines the data and methods for the
factory object. It is nested within the class source element,
immediately following the class source element's Data Division (if there
is one). It looks like this:

factory.
working-storage section.
* factory data .
...
* factory methods
end factory.

The factory object data is defined in the Working-Storage Section.
***The factory object data can only be accessed from the factory
methods*** - my Asterisks.
----------------------------------------------------------------------------
Factory Methods

Each factory method is a nested source element. The code below shows an
outline for a "new" method for Stopwatch.

method-id. "new".
...
linkage section.
01 lnkWatch object reference.

procedure division returning lnkWatch.
* code to create and initialize a Stopwatch object.
exit method.
end method "new".

As with the class source element itself, you can declare different types
of data in the Data Division of the method. The DATA DIVISION header
itself is optional. Data declared here is only accessible to the code in
this method. The Data Division can contain any of the following sections:

* Local-Storage Section

Data items that are local to the current invocation of a method.
The method uses local storage for all its temporary working data. This
has the advantage of supporting recursion.
* Linkage Section

Variables passed as parameters to and from the method.

The Procedure Division contains the code for the method. You terminate
processing of the method with an EXIT METHOD statement. This returns
processing to the program which invoked the method.

To see the "new" method, use the Editor to locate the "new" method,
below tag S015. This method uses a Linkage Section to return data from
the method.
The Instance Object Source Element

The instance object source element defines the data and methods for
instances of the class. It is nested within the class source element. It
looks like this:

object.
working-storage section.
* instance data for the object.
...
* Instance methods
end object.

The only Data Division section that has any meaning in an object source
element is the Working-Storage Section. You can create other data
sections, but the run-time behavior if you try to access the data in
these sections is undefined.

Any data you declare in the Working-Storage Section is accessible to all
the instance methods, and may be inherited by instances of subclasses of
the class.

There is no Procedure Division in an object source element, only
methods. To write an initialization method for instances, write a method
called "initialize", and then invoke it from the "new" method for the
class after you have created an instance.

To see the object source element and data declarations paragraph for
Stopwatch, use the Editor to locate the OBJECT header. The OBJECT header
and Working-Storage Sections are located below tags S030 and S035.
Instance Methods

Instance methods are nested inside the object source element. Writing an
instance method is exactly like writing a factory method, with the only
difference being the scope of data which the instance method can access.

The instance method can access data:

* Declared in the Data Division of the instance method source element

* Declared in the Working-Storage Section of the object source element
----------------------------------------------------------------------------

Now just tracking to N/E sample on 'Bank Accounts' - what else; that's
what they all use. They do use FACTORY similar to above to create a new
account. But is that just doing it by rote because that's the perceived
way that everybody does it, regardless of language. Or are FACTORY
methods irrelevant and they could be contained in the OBJECT ?

You Java boys convey how static gets used in Java, to counter what I've
written above.

Pete, above is not complete references. However where it says, "***The
factory object data can only be accessed from the factory methods*** ".
If you are passing parameters/properties for Components to FACTORY how
do they get referenced from Instance/Object methods ?

Jimmy
Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com