예제 #1
0
        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);
        }