Seriously???!!!??? Strange OOABL behavior

Posted by PapaLee on 09-Jun-2017 23:03

OpenEdge 11.5.1 64 bit, Windows 10 and OpenEdge 10.2b AIX 64 bit

I'm a bit new to OOABL and I probably missed the memo, but can someone please explain just how in the sam ... this compiles (Sports2000 database):

using Progress.Lang.*.
class myClass:
   method public void method1():
      for each department
            no-lock:
         display
            customer.custNum.
      end.
   end method.
end class.

Of course there's a run time error. But is it unreasonable to expect the compile do it's job and not allow it before it gets to running?

I checked a normal .p and the compiler complains just like one would expect.

TIA

All Replies

Posted by Brian K. Maher on 10-Jun-2017 04:18

This does the same in 11.7.  It’s a bug.  Can you open a case with support so we can get this logged?
 

Posted by dbeavon on 10-Jun-2017 20:19

Are we sure it is a bug?  OE's OO classes have a number of oddities in the way that various data types are scoped.  It would be nice if the scope of some things like temp-tables and, in this case, buffers would be limited to the context of a method.  Unfortunately that is not the way classes work.  I'm told it is for legacy reasons. The scope of your buffers and temp tables is at the class level, like an instance member.

For example, I've often run into issues where a buffer will be moved with FIND in one method call, and then another nested method call will move the buffer again, so that when control returns to the outer method, the buffer is either lost or not on the same record as it was when the inner method was started.

Because buffers have class-level scopes instead of method-level scopes, it is possible that this behavior is by design.  The only way the compiler could easily tell that you didn't intend to actually use the customer buffer is if record buffers were scoped at the method level.

Posted by Mike Fechner on 10-Jun-2017 21:58

IMHO a good practice is to DEFINE BUFFER Customer FOR Customer in each and every method (that requires that buffer).

Sent from Nine

Von: dbeavon <bounce-dbeavon@community.progress.com>
Gesendet: 10.06.2017 9:20 nachm.
An: TU.OE.Development@community.progress.com
Betreff: RE: [Technical Users - OE Development] Seriously???!!!??? Strange OOABL behavior

Update from Progress Community
dbeavon

Are we sure it is a bug?  OE's OO classes have a number of oddities in the way that various data types are scoped.  It would be nice if the scope of some things like temp-tables and, in this case, buffers would be limited to the context of a method.  Unfortunately that is not the way classes work.  I'm told it is for legacy reasons. The scope of your buffers and temp tables is at the class level, like an instance member.

For example, I've often run into issues where a buffer will be moved with FIND in one method call, and then another nested method call will move the buffer again, so that when control returns to the outer method, the buffer is either lost or not on the same record as it was when the inner method was started.

Because buffers have class-level scopes instead of method-level scopes, it is possible that this behavior is by design.  The only way the compiler could easily tell that you didn't intend to actually use the customer buffer is if record buffers were scoped at the method level.

View online

 

You received this notification because you subscribed to the forum.  To unsubscribe from only this thread, go here.

Flag this post as spam/abuse.

Posted by smat-consulting on 10-Jun-2017 22:40

Re Mike:

I prefer to use DEFINE BUFFER bufCustomer FOR customer.

It is very obvious if I am referring to a buffer without the bug prefix. And it doesn't compile if I am missing the define buffer statement. If I were to use the same name as the table, it is not at all obvious if I am missing a define buffer statement. And if you happen to make the same mistake in two methods or procedures, you have the scoping problem - which is a real hassle of a bug to find...

But, yes, I also do recommend strongly ( strongliest! :) ) to define buffers for every table you're using in a method, function or procedure.

Posted by smat-consulting on 10-Jun-2017 22:48

I haven't done anything with the OOABL, so I am curious:

If I have a class A that inherits from another class B, where B has a buffer scoped to the whole class: would that buffer be

available in the inheriting class A automatically, or would it have to be defined again? Second option doesn't seem right to me. First option would make it impossible for a compiler to know whether a buffer is in scope and has a record or not.

Thank you for your insights...

PS: I hardly ever use anything scoped to the whole file, but always pass everything explicitly into the procedure or function, explicitly stating whether it is an INPUT, INPUT-OUTPUT, or OUTPUT parameter. That way it is clear what change is going to make it outside of that thing, and what not. That seems to be even more important with OOABL. Is that so?

Posted by PapaLee on 11-Jun-2017 00:29

dbeavon,

If customer was available somewhere in the class, it would not be an issue, just a typo. But the fact that the only buffer available anywhere in the class is department makes it a bug IMO.

The following .p does not compile:

/* myProc.p */

for each department no-lock:

   display customer.CustNum.

end.

Posted by PapaLee on 11-Jun-2017 20:15

New Case 00403890

Posted by PapaLee on 11-Jun-2017 20:31

Thomas,

Whether or not resources of a parent/super class are available to it's offspring/sub-classes is as much scope as access-mode.

Class B has protected buffer. (Note, public buffers are not supported as are other class elements)

Class A has full knowledge of that buffer without it being redefined.

OTOH

Class B has private buffer.

Class A has no knowledge of that buffer.

HTH

Posted by dbeavon on 12-Jun-2017 07:33

If you are going to compare against a "normal .P", then you might try this as well.

RUN Test.
RETURN.


PROCEDURE Test:

for each department no-lock:

   display customer.custnum.

end.
   
END PROCEDURE. 

This thread is closed