Kotlin: double colon (reflection) operator over - reflection

So I was working with VertX Web, trying to make it work with Kotlin.
There's a router and you have to say something like
val vertx = Vertx.vertx()
val server = vertx.createHttpServer()
val router = Router.router(vertx)
server.requestHandler(router::accept)
But it doesn't work. What am I doing wrong? When I use it on Kotlin defined classes, it behaves normally. Is it done on purpose?
Whatever, I had to do it manually like this
server.requestHandler{router.accept(it)}

It is a known bug.
See this issue.
A workaround is to use a Lambda instead. e.g.
class Foo {
fun doWork(work: () -> Unit) {
work()
}
}
class Bar (val text: String) {
fun printText() {
println("${text}")
}
}
val foo: Foo = Foo()
val bar: Bar = Bar("Hello Kotlin!")
foo.doWork(bar::printText) //Fails
foo.doWork({ bar.printText() }) //Is working

Technically it's not a bug. I asked early on if they planned to support method references on instances in version 1, and I was told that they most likely wouldn't.
Method references can only be used from classes and modules, not from instances. Coming from Java 8, this seems like a big deal, but considering the potential conciseness of their lambda syntax, it really isn't.
UPDATE: They plan to add this feature in 1.1

Related

How to know if a method has been defined in an interface

Given the following code:
interface MyInterface {
fun foo() {
// body
}
fun bar() {
// body
}
}
class MyInterfaceImpl: MyInterface {
override fun bar() {
// body
}
}
I need to know at runtime that bar() has been overridden and foo() hasn't. How to do this using reflection?
Note: java.lang.reflect.Method#getDeclaringClass() always returns MyInterfaceImpl::class.java and java.lang.reflect.Method#isDefault() always returns false. I did not find the solution in KClass.
From what I know, where are two ways to achieve that dubious goal.
I'll demonstrate easy one, and discuss idea behind the harder one.
Easy one is based on simply calling toString() on the method:
val functions = MyInterfaceImpl::class.functions
val bar = (functions.toList()[0])
val foo = (functions.toList()[2])
println(bar.toString()) // fun MyInterfaceImpl.bar(): kotlin.Unit
println(foo.toString()) // fun MyInterface.foo(): kotlin.Unit
As you can see, you can figure if the method was overridden or not by parsing the string.
Harder solution would be to dig into KFunctionImpl, which has delegate member, which has dispatchReceiverParameter
That's a lot of nasty reflection, which is even more nasty, because most of those classes are internal and lazily initialized.
We can compare MyInterfaceImpl::class.declaredFunctions and MyInterface::class.declaredFunctions.
This property lists all functions declared in this class.

Writing a Kotlin util function which provides self-reference in initializer

I'm trying to generalize my hack from an answer to another question.
It should provide a way to reference a value which is not constructed yet inside its initializer (of course, not directly, but in lambdas and object expressions).
What I have at the moment:
class SelfReference<T>(val initializer: SelfReference<T>.() -> T) {
val self: T by lazy {
inner ?: throw IllegalStateException("Do not use `self` until initialized.")
}
private val inner = initializer()
}
fun <T> selfReference(initializer: SelfReference<T>.() -> T): T {
return SelfReference(initializer).self
}
It works, see this example:
class Holder(var x: Int = 0,
val action: () -> Unit)
val h: Holder = selfReference { Holder(0) { self.x++ } }
h.action()
h.action()
println(h.x) //2
But at this point the way in which initializer references the constructed value is self property.
And my question is: is there a way to rewrite SelfReference so that initializer is passed an argument (or a receiver) instead of using self property? This question can be reformulated to: is there a way to pass a lazily evaluated receiver/argument to a function or achieve this semantics some way?
What are the other ways to improve the code?
UPD: One possible way is to pass a function that returns self, thus it would be used as it() inside the initializer. Still looking for other ones.
The best I have managed to produce while still being completely generic is this:
class SelfReference<T>(val initializer: SelfReference<T>.() -> T) {
val self: T by lazy {
inner ?: throw IllegalStateException("Do not use `self` until initialized.")
}
private val inner = initializer()
operator fun invoke(): T = self
}
Adding the invoke operator lets you use it in the following way:
val h: Holder = selfReference { Holder(0) { this().x++ } }
This is the closest I got to make it look like something you would "normally" write.
Sadly I think it is not possible to get completely rid of a explicit access to the element. Since to do that you would need a lambda parameter of type T.() -> T but then you wouldn't be able to call that parameter without an instance of Tand being T a generic there is no clean and safe way to acquire this instance.
But maybe I'm wrong and this helps you think of a solution to the problem
is there a way to rewrite SelfReference so that initializer is passed an argument (or a receiver) instead of using self property? This question can be reformulated to: is there a way to pass a lazily evaluated receiver/argument to a function or achieve this semantics some way?
I'm not sure I completely understand your use case but this may be what you're looking for:
fun initHolder(x: Int = 0, holderAction: Holder.() -> Unit) : Holder {
var h: Holder? = null
h = Holder(x) { h!!.holderAction() }
return h
}
val h: Holder = initHolder(0) { x++ }
h.action()
h.action()
println(h.x) // 2
This works because holderAction is a lambda with a receiver (Holder.() -> Unit) giving the lambda access to the receiver's members.
This is a general solution since you may not be able to change the signature of the respective Holder constructor. It may be worth noting this solution does not require the class to be open, otherwise a similar approach could be done with a subclass using a secondary constructor.
I prefer this solution to creating a SelfReference class when there are only a few number of classes that need the change.
You may want to check for null instead of using !! in order to throw a helpful error. If Holder calls action in it's constructor or init block, you'll get a null pointer exception.
I'm pretty sure you can achieve the same results in a more readable and clear way using something like this:
fun <T> selfReferenced(initializer: () -> T) = initializer.invoke()
operator fun<T> T.getValue(any: Any?, property: KProperty<*>) = this
and later use
val valueName: ValueType by selfReferenced{
//here you can create and use the valueName object
}
Using as example your quoted question https://stackoverflow.com/a/35050722/2196460 you can do this:
val textToSpeech:TextToSpeech by selfReferenced {
TextToSpeech(
App.instance,
TextToSpeech.OnInitListener { status ->
if (status == TextToSpeech.SUCCESS) {
textToSpeech.setLanguage(Locale.UK)
}
})
}
Inside the selfReferenced block you can use the outer object with no restrictions. The only thing you should take care of, is declaring the type explicitly to avoid recursive type checking issues.

Observing changes to ES6 Maps and Sets

Is there any way to observe additions to and removals from ES6 Maps and Sets? Object.observe doesn't work because it is only applies to direct properties of the observed object. Hypothetically the size property could be observed, but no indication would be provided of exactly what has changed. Another idea would be to replace the object's set and get functions with proxified versions. Is there a better way? If not, I'm surprised that nobody thought of this when the proposals were being written for ES6.
No, there is no way to do this with a vanilla Map/Set. In general observation of object properties alone is controversial (that is why Object.observe is only a proposal, and not an accepted part of the spec). Observing private state, like the internals of a Map or Set (or Date or Promise, for that matter), is definitely not on the table.
Note also that since size is a getter, not a data property, Object.observe will not notify you of changes to it.
As you mention, you can achieve such "observation" via collaboration between the mutator and the observer. You could either do this with a normal Map/Set plus a side-channel (e.g. a function returning a { Map, EventEmitter } object), or via a subclass tailored for the purpose, or a specific instance created for that purpose.
Subclassing for Set/Map is not working at the moment. How about this method (just hasty example)?
//ECMAScript 2015
class XMap
{
constructor(iterable, observer = null)
{
this._map = new Map(iterable);
this._observer = observer;
this._changes = {};
}
set(key, value)
{
this._changes.prev = this._map.get(key);
this._changes.new = value;
this._map.set(key, value);
if(this._observer !== null)
{
this._observer(this._changes);
}
}
get(key)
{
return this._map.get(key);
}
}
var m = new XMap([[0, 1]], changes => console.log(changes));
m.set(0,5); // console: Object {prev: 1, new: 5}
m.set(0,15); // console: Object {prev: 5, new: 15}

Using Recursive References in Go

I want to contain all my commands in a map and map from the command to a function doing the job (just a standard dispatch table). I started with the following code:
package main
import "fmt"
func hello() {
fmt.Print("Hello World!")
}
func list() {
for key, _ := range whatever {
fmt.Print(key)
}
}
var whatever = map[string](func()) {
"hello": hello,
"list": list,
}
However, it fails to compile because there is a recursive reference between the function and the structure. Trying to forward-declare the function fails with an error about re-definition when it is defined, and the map is at top-level. How do you define structures like this and initialize them on top level without having to use an init() function.
I see no good explanation in the language definition.
The forward-reference that exists is for "external" functions and it does not compile when I try to forward-declare the function.
I find no way to forward-declare the variable either.
Update: I'm looking for a solution that do not require you to populate the variable explicitly when you start the program nor in an init() function. Not sure if that is possible at all, but it works in all comparable languages I know of.
Update 2: FigmentEngine suggested an approach that I gave as answer below. It can handle recursive types and also allow static initialization of the map of all commands.
As you might already have found, the Go specifications states (my emphasis):
if the initializer of A depends on B, A will be set after B. Dependency analysis does not depend on the actual values of the items being initialized, only on their appearance in the source. A depends on B if the value of A contains a mention of B, contains a value whose initializer mentions B, or mentions a function that mentions B, recursively. It is an error if such dependencies form a cycle.
So, no, it is not possible to do what you are trying to do. Issue 1817 mentions this problem, and Russ Cox does say that the approach in Go might occasionally be over-restrictive. But it is clear and well defined, and workarounds are available.
So, the way to go around it is still by using init(). Sorry.
Based on the suggestion by FigmentEngine above, it is actually possible to create a statically initialized array of commands. You have, however, to pre-declare a type that you pass to the functions. I give the re-written example below, since it is likely to be useful to others.
Let's call the new type Context. It can contain a circular reference as below.
type Context struct {
commands map[string]func(Context)
}
Once that is done, it is possible to declare the array on top level like this:
var context = Context {
commands: map[string]func(Context) {
"hello": hello,
"list": list,
},
}
Note that it is perfectly OK to refer to functions defined later in the file, so we can now introduce the functions:
func hello(ctx Context) {
fmt.Print("Hello World!")
}
func list(ctx Context) {
for key, _ := range ctx.commands {
fmt.Print(key)
}
}
With that done, we can create a main function that will call each of the functions in the declared context:
func main() {
for key, fn := range context.commands {
fmt.Printf("Calling %q\n", key)
fn(context)
}
}
Just populate the map inside a function before using list(). Like that.
Sry I did not see that you wrote "without init()": that is not possible.

Flash Player: Get reference count for variable

I'm looking to build a library that needs to be very careful about memory management. Basically, I have to create a static factory to "disperse" instances of my tool to requesting objects. (I don't have a choice in this matter, I really do have to use a singleton) We'll call that class FooFactory. FooFactory defines a single method, getFoo(key:String):Foo.
getFoo looks in a private static flash.utils.Dictionary object for the appropriate Foo instance, and either lazy-instantiates it, or simply returns it. In any case, FooFactory MUST keep a reference to each Foo instance created, so all Foo instances can be updated by FooFactory using a method called updateFoos():void.
Here is some pseudo-code of what I'm talking about:
public class FooFactory {
private static const foos:Dictionary = new Dictionary(true); //use weak keys for gc
public static function getFoo(key:String):Foo {
//search for the specified instance in the 'foos' dictionary
if (foos[key] != null && foos[key] != undefined) {
return foos[key];
} else {
//create foo if it doesn't exist.
var foo:Foo = new Foo(key);
foos[key] = foo;
return foo;
}
}
public static function updateFoos():void {
for (var key:String in foos) {
if (foos[key] != null && foos[key] != undefined) {
Foo(foos[key]).dispatchEvent(new Event("update"));
}
}
}
}
The actual function and identity of Foo isn't too important.
What IS important is garbage collection in this situation. I created something similar to the above example in the past and had incredible garbage collection issues. (I did use an array rather than a dictionary, which could be part of the problem.) What would happen is that, in my Flex application, modules would never unload, since instances had a reference to a Foo instance which was referenced by the FooFactory, like so: (again, pseudocode)
<?xml version="1.0"?>
<s:Group>
<fx:Script>
<![CDATA[
private static const foo:Foo = FooFactory.getFoo('myfoo');
]]>
</fx:Script>
</s:Group>
What I want to know are the two following things:
Is the pseudo-code above "garbage-collector safe?" IE: Will my modules unload properly and will instances of the Group subclass above get garbage collected?
Is there a way in Flash Player (even in the debug player if need be) that can assist me in counting references so I can test if things are getting garbage collected or not?
I'm aware of the flash.sampler API, but I am not sure as to how to use it to count references.
I don't think that the pattern you presented should give you problems GC-wise.
private static const foo:Foo = FooFactory.getFoo('myfoo');
Here, your module has a reference to a Foo instance. That means that this Foo instance won't be collectable as long as your module is not collectable. The module has a reference to foo, so here foo is reachable (if the module is reachable). That's not true the other way round. Even if foo lives forever, it doesn't have a reference to the module, so it won't pint it down.
Of course there could be other stuff going on to prevent your module from being collectable, but foo is not the culprit here, unless foo gets a reference to the module somehow. For instance, the module adds a listener to foo, which for this matter, is the same as writing:
foo.addReference(this); // where this is your module
The fact that you declare the instance as const shouldn't change things per se, either. It only means that the reference stored cannot be changed at a later point. However, if you want to null out foo at some later point, you can't because that would be reassigning the reference; and you can't reassigning a const reference (you should get a compiler error). Now, this does tie foo to module. As long as your module is alive it will have a reference to foo, so foo won't be collectable.
Regarding this line:
private static const foos:Dictionary = new Dictionary(true); //use weak keys for gc
It looks like you're trying to build some kind of cache. I'm not sure you want to use weak refs here. (I could be wrong here because I'm making an assumption, and they say assumption is the mother of all... mistakes, but I digress)
In any case, the effect of this is that if a module gets a Foo and at some point the module is successfully unloaded (I mean, cleaned up from memory), that instance of foo could be collected, provided that no one else has a ref to it (that is, the only way to reach it is through the dictionary key, but since the keys are weak referenced, this ref will not count for the purposes of the GC).
Regarding your second question, I'd recommend the FlexBuilder/FlashBuilder profiler, if FB is available to you. It's not the most intuitive tool, granted, but with some practice it could be really useful to track memory problems. Basically, it will let you know how many instances of a given class were created, how many of those are still alive, what objects have references to these instances and where were all these objects allocated (an option not checked by default when you launch the profiler, buy very handy to track a leak).
PS
Regarding your comment:
Perhaps the real issue is the static
const reference bound by the Group
instance? If that's an issue, I could
simply abstract Foo to an interface,
then create something called
FooWeakReference which would use a
weak dictionary to reference the
actual Foo object. Thoughts?
Adding this extra layer of indirection only complicates things and makes your code less obvious for no gain here, I think. It's easier to consider the life-cycle of your module and define clear points of initialization and finalization. When it's finalized, make sure you remove any reference to the module added to the foo instance (i.e. if you have added listeners on foo, remove them, etc), so your module is collectable independently of the life-cycle of foo.
As a general rule, whenever a weak reference seems to solve a bug in your app, it's masking another one or covering up for a poor design; there are exceptions (and compromises that have to be made sometimes), but weak refs are abused gratuitously if you ask me; not everyone will agree, I know.
Also, weak-refs open a whole new kind of bugs: what happens if that instance you created lazily vanishes before you can use it or worse, while you are using it? Event listeners that stop working under not deterministically reproducible circumstances (e.g. you added a listener to an object that is gone), possible null references (e.g. you are trying to add a listener to an object that no longer exists), etc, etc. Don't drink the weak reference kool-aid ;).
Addedum
In conclusion, as one last question,
is it true for me to say that no AS3
solution exists for counting
references? I'm building a complete
unit-testing suite for this library
I'm building, and if I could do
something like Assert.assertEquals(0,
getReferenceCount(foo)), that would be
rad.
Well, yes. You can't get the reference count of a given object from Actionscript. Even if it were possible, I'm not sure that would help, because reference counting is only a part of how GC works. The other one is a mark and sweep algorithm. So, if an object has a zero ref-count is collectable, but it could have, say, 3 references and still be collectable. To really determine whether an object is collectable or not, you should really be able to hook into the GC routine, I guess, and that's not possible from AS.
Also, this code will never work.
Assert.assertEquals(0, getReferenceCount(foo)
Why? Here you are trying to query some API to know whether an object is collectable or not. Since you can't know that, let's assume this tells you whether an object has been collected or not. The problem is, foo at that point is either null or not null. If it's null, it's not a valid reference, so you can't get any useful information out of it, for obvious reasons. If it's not null, it's a valid reference to an object, then you can access it and it's alive; so you already know the answer to the question you're asking.
Now, I think I undestand your goal. You want to be able to tell, programatically, if you certain objects are being leaked. Up to some extent that's possible. It involves using the flash.sampler API, as you mentioned in your original question.
I suggest you check out the Flash Preload Profiler by jpauclair:
I haven't used it, but it looks like it could be just as good as the FB profiler for memory watching.
Since this is Actionscript code (and since it's open source), you could to use it for what you want. I just skimmed through the code, but I've been able to get a very simple-minded proof of concept by monkey-patching the SampleAnalyzer class:
There's a lot of other things going on in this tool, but I just modified the memory analizer to be able to return a list of the alive objects.
So, I wrote a simple class that would run this profiler. The idea is that when you create an object, you can ask this class to watch it. This objects' allocation id will be looked up in the allocated objects table maintained by the memory profiler and a handle to it will be stored locally (only the id). This id handle will also be returned for convenience. So you can store this id handle and at a later point, use it to check whether the object has been collected or not. Also, there's a method that returns a list of all the handles you added and another one that returns a list of the added handles that point to live objects. A handle will allow you to access the original object (if it hasn't been collected yet), its class and also the allocation stack trace. (I'm not storing the object itself or the NewObjectSample object to avoid accidentally pinning it down)
Now, this is important: this queries for alive objects. The fact that an object is alive doesn't mean it's not collectable. So, this alone doens't mean there's a leak. It could be alive at this point but still it doesn't mean there's a leak. So, you should combine this with forcing GC to get more relevant results. Also, this could be of use if you are watching objects that are owned by you and not shared with other code (or other modules).
So, here's the code to the ProfileRunner, with some comments.
import flash.sampler.Sample;
import flash.sampler.NewObjectSample;
import flash.utils.Dictionary;
class ProfilerRunner {
private var _watched:Array;
public function ProfilerRunner() {
_watched = [];
}
public function init():void {
// setup the analyzer. I just copied this almost verbatim
// from SamplerProfiler...
// https://code.google.com/p/flashpreloadprofiler/source/browse/trunk/src/SamplerProfiler.as
SampleAnalyzer.GetInstance().ResetStats();
SampleAnalyzer.GetInstance().ObjectStatsEnabled = true;
SampleAnalyzer.GetInstance().InternalEventStatsEnabled = false;
SampleAnalyzer.GetInstance().StartSampling();
}
public function destroy():void {
_watched = null;
}
private function updateSampling(hook:Function = null):void {
SampleAnalyzer.GetInstance().PauseSampling();
SampleAnalyzer.GetInstance().ProcessSampling();
if(hook is Function) {
var samples:Dictionary = SampleAnalyzer.GetInstance().GetRawSamplesDict();
hook(samples);
}
SampleAnalyzer.GetInstance().ClearSamples();
SampleAnalyzer.GetInstance().ResumeSampling();
}
public function addWatch(object:Object):WatchHandle {
var handle:WatchHandle;
updateSampling(function(samples:Dictionary):void {
for each(var sample:Sample in samples) {
var newSample:NewObjectSample;
if((newSample = sample as NewObjectSample) != null) {
if(newSample.object == object) {
handle = new WatchHandle(newSample);
_watched.push(handle);
}
}
}
});
return handle;
}
public function isActive(handle:WatchHandle):Boolean {
var ret:Boolean;
updateSampling(function(samples:Dictionary):void{
for each(var sample:Sample in samples) {
var newSample:NewObjectSample;
if((newSample = sample as NewObjectSample) != null) {
if(newSample.id == handle.id) {
ret = true;
break;
}
}
}
});
return ret;
}
public function getActiveWatchedObjects():Array {
var list:Array = [];
updateSampling(function(samples:Dictionary):void {
for each(var handle:WatchHandle in _watched) {
if(samples[handle.id]) {
list.push(handle);
}
}
});
return list;
}
public function getWatchedObjects():Array {
var list:Array = [];
for each(var handle:WatchHandle in _watched) {
list.push(handle);
}
return list;
}
}
class WatchHandle {
private var _id:int;
private var _objectProxy:Dictionary;
private var _type:Class;
private var _stack:Array;
public function get id():int {
return _id;
}
public function get object():Object {
for(var k:Object in _objectProxy) {
return k;
}
return null;
}
public function get stack():Array {
return _stack;
}
public function getFormattedStack():String {
return "\t" + _stack.join("\n\t");
}
public function WatchHandle(sample:NewObjectSample) {
_id = sample.id;
_objectProxy = new Dictionary(true);
_objectProxy[sample.object] = true;
_type = sample.type;
_stack = sample.stack;
}
public function toString():String {
return "[WatchHandle id: " + _id + ", type: " + _type + ", object: " + object + "]";
}
}
And here's a simple demo of how you'd use it.
It initializes the runner, allocates 2 Foo objects and then, after 2 seconds, it finalizes itself. Note that in the finalizer, I'm nulling out one of the Foo objects and finalizing the profiler. There I try to force GC, wait for some time (GC is not synchronous) and then check if these objects are alive. The first object should return false, and the second true. So, this is the place were you'd put your assert. Keep in mind that all of this will only work in a debug player.
So, without any further addo, here's the sample code:
package {
import flash.display.Sprite;
import flash.sampler.NewObjectSample;
import flash.sampler.Sample;
import flash.system.System;
import flash.utils.Dictionary;
import flash.utils.setTimeout;
public class test extends Sprite
{
private var x1:Foo;
private var x2:Foo;
private var _profiler:ProfilerRunner;
private var _watch_x1:WatchHandle;
private var _watch_x2:WatchHandle;
public function test()
{
init();
createObjects();
setTimeout(finalize,2000);
}
public function init():void {
initProfiler();
}
public function finalize():void {
x1 = null;
finalizeProfiler();
}
private function initProfiler():void {
_profiler = new ProfilerRunner();
_profiler.init();
}
private function finalizeProfiler():void {
// sometimes, calling System.gc() in one frame doesn't work
// you have to call it repeatedly. This is a kind of lame workaround
// this should probably be hidden in the profiler runner
var count:int = 0;
var id:int = setInterval(function():void {
System.gc();
count++;
if(count >= 3) {
clearInterval(id);
destroyProfiler();
}
},100);
}
private function destroyProfiler():void {
// boolean check through saved handles
trace(_profiler.isActive(_watch_x1));
trace(_profiler.isActive(_watch_x2));
// print all objects being watched
trace(_profiler.getWatchedObjects());
// get a list of the active objects and print them, plus the alloc stack trace
var activeObjs:Array = _profiler.getActiveWatchedObjects();
for each(var handle:WatchHandle in activeObjs) {
trace(handle);
trace(handle.getFormattedStack());
}
_profiler.destroy();
}
private function createObjects():void {
x1 = new Foo();
x2 = new Foo();
// add them for watch. Also, let's keep a "handle" to
// them so we can query the profiler to know if the object
// is alive or not at any given time
_watch_x1 = _profiler.addWatch(x1);
_watch_x2 = _profiler.addWatch(x2);
}
}
}
import flash.display.Sprite;
class Foo {
public var someProp:Sprite;
}
Alternatively, a more light-weight approach for tracking alive objects is storing them in a weak-referenced dictionary, forcing GC and then checking how many objects are stil alive. Check out this answer to see how this could be implemented. The main difference is that this gives you less control, but maybe it's good enough for your purposes. Anyway, I felt like giving the other idea a shot, so I wrote this object watcher and kind of like the idea.
Since you essentially want weak references, perhaps the best solution would involve one of the weak references available in AS3.
For example, have your method store Dictionaries rather than the actual objects. Something like this:
private var allFoos:Dictionary;
public function getFoo(key:String):Foo {
var f:Foo = _getFoo(key);
if (f == null) {
f = _createFoo(key);
}
return f;
}
private function _createFoo(key:String):Foo {
var f:Foo = new Foo();
var d:Dictionary = new Dictionary(/* use weak keys */ true);
d[f] = key;
allFoos[key] = d;
}
With some intense thinking over the weekend, I believe I figured out what the problem is.
Essentially, we have this scenario:
.--------------.
| APP-DOMAIN 1 |
| [FooFactory] |
'--------------'
|
| < [object Foo]
|
.--------------.
| APP-DOMAIN 2 |
| [MyModule] |
'--------------'
APP-DOMAIN 1 always stays in memory, since it's loaded in the highest app-domain possible: the original compiled code of a SWF. APP-DOMAIN 2 is loaded into and out of memory dynamically and must be able to completely sever itself from APP-DOMAIN 1. According to the genius answer above by Juan Pablo Califano, APP-DOMAIN 2 having a reference to [object Foo] doesn't necessarily tie APP-DOMAIN 2 into memory, though it could become tied into memory by [MyModule] adding an event listener to [object Foo], right?
Okay, so, with this in mind, an overkill solution would be to return a weak-reference-implementation of Foo from the getFoo method, since that's where things need to "break off" in case of "emergency." (Things need to be weak from this perspective so that APP-DOMAIN 1 can be garbage collected completely as it is unloaded.) Again, this is an overkill answer.
However, I do not need to keep a weak-ref to Foo in FooFactory, since FooFactory needs to have a surefire way of getting a hold of each created Foo object. In short, Juan Pablo Califano has the theory completely right, it just needs to be tested in the real world in order to prove everything definitively :)
All of this aside, I believe I have uncovered the real issue behind the scenes that caused a similar library I wrote in the past to never GC. The problem was not in the actual library I wrote, but it seems that it was in a reflection library I was using. The reflection library would "cache" every Class object I threw at it, since my original FooFactory.getFoo method took a Class parameter, rather than a String. Since the library seemed to be hard-referencing every Class object passed into memory, I'm pretty sure that was the memory leak.
In conclusion, as one last question, is it true for me to say that no AS3 solution exists for counting references? I'm building a complete unit-testing suite for this library I'm building, and if I could do something like Assert.assertEquals(0, getReferenceCount(foo)), that would be rad.

Resources