From: Rick M. <obj...@gm...> - 2013-06-17 15:42:58
|
.package~new will ALWAYS load the file and create a new package object. It also does not add the loaded package to the global cache. loadPackage() is the part that is aware of the cache, and if the package has not previously been loaded, then will create a new package object and add it to the cache. loadPackage uses .package~new to accomplish what it does. Rick On Mon, Jun 17, 2013 at 11:30 AM, Mark Miesfeld <mie...@gm...> wrote: > Fooling around with the .Package class a week ago, I see a difference in > behavior between using loadPackage('myFile') and .Package~new('myFile') > that I don't understand. I wonder if this is intentional or not. > > Say I have a very simple file: mypackage.cls. Having skimmed the docs > some time ago, I had the feeling that these 3 statements were all > equivalent: > > ::requires 'mypackage.cls' > > .Package~new('mypackage.cls') > > packageObj~loadPackage('mypackage.cls') > > And, since 4.0, I thought that in one single interpreter process, the > ::requires 'mypackage.cls' would only load mypackage.cls once. > > However, in a large number of iterations, I see that > .Package~new('mypackage.cls') will sometimes return a new .Package object > and reload the mypackage.cls file. Whereas > packageObj~loadPackage('mypackage.cls') always returns the same .Package > object and does not reload mypackage.cls > > The code for a simple test showing this is below. > > I don't understand why the behavior between the two is different. I > expected both to only load the mypackage.cls file once. But, in the > PackageManager class I see this code / comment: > > WeakReference *requiresRef = (WeakReference > *)loadedRequires->get(name); > if (requiresRef != OREF_NULL) > { > RoutineClass *resolved = (RoutineClass *)requiresRef->get(); > if (resolved != OREF_NULL) > { > result = resolved; > return resolved; > } > // this was garbage collected, remove it from the table > loadedRequires->remove(name); > } > return OREF_NULL; > > The "this was garbage collected" comment makes it seem like it might be > expected that the same .Package object might not always be returned. But, > then why don't both approaches do the same thing? > > Here is a simple program that shows the 'mypackage.cls' is reloaded > sometimes: > > /* mypackage.cls */ > say 'mypackage.cls loaded' > exit > > > /* packageNew.rex */ > obj1 = .Thread~new('thread 1') > obj2 = .Thread~new('thread 2') > > obj1~work > obj2~work > > ::class 'Thread' > > ::method init > expose name > use arg name > > ::method work unguarded > expose name > reply 0 > > str = '1' > e = time('e') > stopTime = 5 > > do while .true > src = .Array~new(4) > src[1] = "use arg name" > src[2] = "p = .package~new('mypackage.cls')" > src[3] = "say name 'p identiy hash' p~identityHash" > src[4] = "return 0" > > rtn = .Routine~new('myRoutine', src) > ret = rtn~call(name) > > str += '1' > if str > 1000 then do > str = '1' > if time('e') > stopTime then leave > end > end > > Run the above like this: > > packageNew.rex > packNew.log > > It runs for about 5 seconds. I see that typically the prolog is executed > about 35 times, when I expected it to be only executed once. > > This is the same program, but the routine's source array is changed to use > loadPackage(): > > /* loadPackage.rex */ > obj1 = .Thread~new('thread 1') > obj2 = .Thread~new('thread 2') > > obj1~work > obj2~work > > ::class 'Thread' > > ::method init > expose name > use arg name > > ::method work unguarded > expose name > reply 0 > > str = '1' > e = time('e') > stopTime = 10 > > do while .true > src = .Array~new(5) > src[1] = "use arg name" > src[2] = "currentPackage = .context~package" > src[3] = "p = currentPackage~loadPackage('mypackage.cls')" > src[4] = "say name 'p identiy hash' p~identityHash" > src[5] = "return 0" > > rtn = .Routine~new('myRoutine', src) > ret = rtn~call(name) > > str += '1' > if str > 1000 then do > str = '1' > if time('e') > stopTime then leave > end > end > > For loadPackage() I see that the docs say the file "will be located and > loaded as if it had been named on a ::REQUIRES directive. And "if a > package name has already been loaded by the package manager, the previously > loaded version will be used." > > But, for new() it doesn't actually say that. > > Well, after having written all that, I see that > .Package~new('mypackage.cls') is not documented as working at all. ;-( > > Still it seems to work to a degree. Maybe the documentation needs to be > cleaned up a bit for ~new()? > > -- > Mark Miesfeld > > > ------------------------------------------------------------------------------ > This SF.net email is sponsored by Windows: > > Build for Windows Store. > > http://p.sf.net/sfu/windows-dev2dev > _______________________________________________ > Oorexx-devel mailing list > Oor...@li... > https://lists.sourceforge.net/lists/listinfo/oorexx-devel > > |