public static object EachObject(BlockParam block, RubyModule/*!*/ self, [NotNull]RubyClass/*!*/ theClass) {
Type classType = theClass.GetType();
bool isClass = (classType == typeof(RubyClass));
if (!isClass && classType != typeof(RubyModule)) {
throw new NotSupportedException("each_object only supported for objects of type Class or Module");
}
if (block == null) {
throw RubyExceptions.NoBlockGiven();
}
Dictionary<RubyModule, object> visited = new Dictionary<RubyModule, object>();
Stack<RubyModule> modules = new Stack<RubyModule>();
modules.Push(theClass.Context.ObjectClass);
while (modules.Count > 0) {
RubyModule next = modules.Pop();
RubyClass asClass = next as RubyClass;
if (!isClass || asClass != null) {
object result;
if (block.Yield(next, out result)) {
return result;
}
}
next.EnumerateConstants(delegate(RubyModule module, string name, object value) {
RubyModule constAsModule = (value as RubyModule);
if (constAsModule != null && !visited.ContainsKey(constAsModule)) {
modules.Push(constAsModule);
visited[module] = null;
}
return false;
});
}
return visited.Count;
}