Yield() public method

public Yield ( object &blockResult ) : bool
blockResult object
return bool
Beispiel #1
1
        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;
        }
Beispiel #2
0
 public static object Synchronize(BlockParam criticalSection, RubyMutex/*!*/ self) {
     lock (self._mutex) {
         self._isLocked = true;
         try {
             object result;
             criticalSection.Yield(out result);
             return result;
         } finally {
             self._isLocked = false;
         }
     }
 }
Beispiel #3
0
 public static RubyArray Map(RubyContext/*!*/ context, BlockParam collector, object self) {
     RubyArray result = new RubyArray();
     Each(context, self, Proc.Create(context, delegate(BlockParam/*!*/ selfBlock, object item) {
         if (collector != null) {
             if (collector.Yield(item, out item)) {
                 return item;
             }
         }
         result.Add(item);
         return null;
     }));
     return result;
 }
Beispiel #4
0
        public static object Each(BlockParam block, IEnumerable/*!*/ self) {
            foreach (object obj in self) {
                object result;
                if (block == null) {
                    throw RubyExceptions.NoBlockGiven();
                }

                if (block.Yield(obj, out result)) {
                    return result;
                }
            }
            return self;
        }
Beispiel #5
0
 public static RubyArray Map(CallSiteStorage<EachSite>/*!*/ each, BlockParam collector, object self) {
     RubyArray result = new RubyArray();
     Each(each, self, Proc.Create(each.Context, delegate(BlockParam/*!*/ selfBlock, object _, object item) {
         if (collector != null) {
             if (collector.Yield(item, out item)) {
                 return item;
             }
         }
         result.Add(item);
         return null;
     }));
     return result;
 }
Beispiel #6
0
        public static object EachType(RubyContext/*!*/ context, BlockParam/*!*/ block, TypeGroup/*!*/ self) {
            if (block == null) {
                throw RubyExceptions.NoBlockGiven();
            }

            foreach (Type type in self.Types) {
                RubyModule module = context.GetModule(type);
                object result;
                if (block.Yield(module, out result)) {
                    return result;
                }
            }

            return self;
        }
Beispiel #7
0
        public static object Each(BlockParam block, RubyStruct/*!*/ self)
        {
            if (block == null && self.ItemCount > 0) {
                throw RubyExceptions.NoBlockGiven();
            }

            foreach (var value in self.Values) {
                object result;
                if (block.Yield(value, out result)) {
                    return result;
                }
            }

            return self;
        }
Beispiel #8
0
        public static object EachPair(BlockParam block, RubyStruct/*!*/ self)
        {
            if (block == null && self.ItemCount > 0) {
                throw RubyExceptions.NoBlockGiven();
            }

            var context = self.ImmediateClass.Context;
            foreach (KeyValuePair<string, object> entry in self.GetItems()) {
                object result;
                if (block.Yield(context.EncodeIdentifier(entry.Key), entry.Value, out result)) {
                    return result;
                }
            }

            return self;
        }
Beispiel #9
0
        public static object Trap(
            RubyContext/*!*/ context, 
            BlockParam block, 
            object self, 
            object signalId) {

            if ((signalId is MutableString) && ((MutableString)signalId).ConvertToString() == "INT") {
                context.InterruptSignalHandler = delegate() { object result; block.Yield(out result); };
            } else {
                // TODO: For now, just ignore unknown signals. This should be changed to throw an
                // exception. We are not doing it yet as it is close to the V1 RTM, and throwing
                // an exception might cause some app to misbehave whereas it might have happenned
                // to work if no exception is thrown
            }
            return null;
        }
Beispiel #10
0
        public static object ChangeDirectory(BlockParam block, object/*!*/ self, MutableString dir) {
            string strDir = dir.ConvertToString();

            if (block == null) {
                SetCurrentDirectory(strDir);
                return 0;
            } else {
                string current = Directory.GetCurrentDirectory();
                try {
                    SetCurrentDirectory(strDir);
                    object result;
                    block.Yield(dir, out result);
                    return result;
                } finally {
                    SetCurrentDirectory(current);
                }
            }
        }
Beispiel #11
0
        private static object TrueForItems(CallSiteStorage<EachSite>/*!*/ each, BlockParam predicate, object self, bool expected) {
            bool result = expected;
            Each(each, self, Proc.Create(each.Context, delegate(BlockParam/*!*/ selfBlock, object _, object item) {
                if (predicate != null) {
                    if (predicate.Yield(item, out item)) {
                        return item;
                    }
                }

                bool isTrue = Protocols.IsTrue(item);
                if (isTrue != result) {
                    result = isTrue;
                    return selfBlock.Break(ScriptingRuntimeHelpers.BooleanToObject(isTrue));
                }

                return null;
            }));

            return ScriptingRuntimeHelpers.BooleanToObject(result);
        }
        public static object DeleteIf(RubyContext/*!*/ context, BlockParam block, object/*!*/ self) {
            PlatformAdaptationLayer pal = context.DomainManager.Platform;
            IDictionary variables = pal.GetEnvironmentVariables();
            if (variables.Count > 0 && block == null) {
                throw RubyExceptions.NoBlockGiven();
            }

            foreach (DictionaryEntry entry in variables) {
                MutableString key = MutableString.Create(entry.Key.ToString()).Freeze();
                MutableString value = MutableString.Create(entry.Value.ToString()).Freeze();
                object result;
                if (block.Yield(key, value, out result)) {
                    return result;
                }

                if (RubyOps.IsTrue(result)) {
                    SetVariable(context, self, key, null);
                }
            }
            return self;
        }
Beispiel #13
0
        public static object EachObject(BlockParam block, RubyModule/*!*/ self, [NotNull]RubyClass/*!*/ theClass)
        {
            if (!theClass.HasAncestor(self.Context.ModuleClass)) {
                throw RubyExceptions.CreateRuntimeError("each_object only supported for objects of type Class or Module");
            }

            if (block == null) {
                throw RubyExceptions.NoBlockGiven();
            }

            int matches = 0;
            List<RubyModule> visitedModules = new List<RubyModule>();
            Stack<RubyModule> pendingModules = new Stack<RubyModule>();
            pendingModules.Push(theClass.Context.ObjectClass);

            while (pendingModules.Count > 0) {
                RubyModule next = pendingModules.Pop();
                visitedModules.Add(next);

                if (theClass.Context.IsKindOf(next, theClass)) {
                    matches++;

                    object result;
                    if (block.Yield(next, out result)) {
                        return result;
                    }
                }

                using (theClass.Context.ClassHierarchyLocker()) {
                    next.EnumerateConstants(delegate(RubyModule module, string name, object value) {
                        RubyModule constAsModule = value as RubyModule;
                        if (constAsModule != null && !visitedModules.Contains(constAsModule)) {
                            pendingModules.Push(constAsModule);
                        }
                        return false;
                    });
                }
            }
            return matches;
        }
Beispiel #14
0
        private static object TrueForItems(CallSiteStorage<EachSite>/*!*/ each, BlockParam predicate, object self, bool stop, bool positiveResult) {
            object result = ScriptingRuntimeHelpers.BooleanToObject(!positiveResult);
            Each(each, self, Proc.Create(each.Context, delegate(BlockParam/*!*/ selfBlock, object _, object item) {
                if (predicate != null) {
                    object blockResult;
                    if (predicate.Yield(item, out blockResult)) {
                        result = blockResult;
                        return selfBlock.PropagateFlow(predicate, blockResult);
                    }
                    item = blockResult;
                }

                bool isTrue = Protocols.IsTrue(item);
                if (isTrue == stop) {
                    result = ScriptingRuntimeHelpers.BooleanToObject(positiveResult); 
                    return selfBlock.Break(result);
                }

                return null;
            }));

            return result;
        }
Beispiel #15
0
            public static object GetProfile(RubyContext/*!*/ context, BlockParam/*!*/ block, object self) {
                if (!((RubyOptions)context.Options).Profile) {
                    throw RubyExceptions.CreateSystemCallError("You must enable profiling to use Clr.profile");
                }

                var start = Profiler.Instance.GetProfile();
                object blockResult;
                if (block.Yield(out blockResult)) {
                    return blockResult;
                }

                Hash result = new Hash(context);
                foreach (var entry in Profiler.Instance.GetProfile()) {
                    long startTime;
                    if (!start.TryGetValue(entry.Key, out startTime)) {
                        startTime = 0;
                    }
                    long elapsed = entry.Value - startTime;
                    if (elapsed > 0) {
                        result[entry.Key] = Protocols.Normalize(Utils.DateTimeTicksFromStopwatch(elapsed));
                    }
                }
                return result;
            }
Beispiel #16
0
        public static RubyArray/*!*/ SortBy(
            CallSiteStorage<EachSite>/*!*/ each, 
            BinaryOpStorage/*!*/ comparisonStorage,
            BinaryOpStorage/*!*/ lessThanStorage,
            BinaryOpStorage/*!*/ greaterThanStorage,
            BlockParam keySelector, object self) {

            // collect key, value pairs
            List<KeyValuePair<object, object>> keyValuePairs = new List<KeyValuePair<object, object>>();

            // Collect the key, value pairs
            Each(each, self, Proc.Create(each.Context, delegate(BlockParam/*!*/ selfBlock, object _, object item) {
                if (keySelector == null) {
                    throw RubyExceptions.NoBlockGiven();
                }

                object key;
                if (keySelector.Yield(item, out key)) {
                    return key;
                }

                keyValuePairs.Add(new KeyValuePair<object, object>(key, item));
                return null;
            }));

            // sort by keys
            keyValuePairs.Sort(delegate(KeyValuePair<object, object> x, KeyValuePair<object, object> y) {
                return Protocols.Compare(comparisonStorage, lessThanStorage, greaterThanStorage, x.Key, y.Key);
            });

            // return values
            RubyArray result = new RubyArray(keyValuePairs.Count);
            foreach (KeyValuePair<object, object> pair in keyValuePairs) {
                result.Add(pair.Value);
            }

            return result;
        }
Beispiel #17
0
        public static RubyArray/*!*/ Partition(CallSiteStorage<EachSite>/*!*/ each, BlockParam predicate, object self) {
            RubyArray trueSet = new RubyArray();
            RubyArray falseSet = new RubyArray();

            Each(each, self, Proc.Create(each.Context, delegate(BlockParam/*!*/ selfBlock, object _, object item) {
                if (predicate == null) {
                    throw RubyExceptions.NoBlockGiven();
                }

                object blockResult;
                if (predicate.Yield(item, out blockResult)) {
                    return blockResult;
                }

                if (Protocols.IsTrue(blockResult)) {
                    trueSet.Add(item);
                } else {
                    falseSet.Add(item);
                }

                return null;
            }));

            RubyArray pair = new RubyArray(2);
            pair.Add(trueSet);
            pair.Add(falseSet);
            return pair;
        }
Beispiel #18
0
        private static object GetExtreme(
            CallSiteStorage<EachSite>/*!*/ each, 
            BinaryOpStorage/*!*/ compareStorage,
            BinaryOpStorage/*!*/ lessThanStorage,
            BinaryOpStorage/*!*/ greaterThanStorage,
            BlockParam comparer, object self, int comparisonValue) {

            bool firstItem = true;
            object result = null;

            Each(each, self, Proc.Create(each.Context, delegate(BlockParam/*!*/ selfBlock, object _, object item) {
                // Check for first element
                if (firstItem) {
                    result = item;
                    firstItem = false;
                    return null;
                }

                int compareResult;
                if (comparer != null) {
                    object blockResult;
                    if (comparer.Yield(result, item, out blockResult)) {
                        return blockResult;
                    }

                    if (blockResult == null) {
                        throw RubyExceptions.MakeComparisonError(selfBlock.RubyContext, result, item);
                    }

                    compareResult = Protocols.ConvertCompareResult(lessThanStorage, greaterThanStorage, blockResult);
                } else {
                    compareResult = Protocols.Compare(compareStorage, lessThanStorage, greaterThanStorage, result, item);
                }

                // Check if we have found the new minimum or maximum (-1 to select max, 1 to select min)
                if (compareResult == comparisonValue) {
                    result = item;
                }

                return null;
            }));
            return result;
        }
Beispiel #19
0
        public static object Inject(CallSiteStorage<EachSite>/*!*/ each, BlockParam operation, object self, [Optional]object initial) {

            object result = initial;
            Each(each, self, Proc.Create(each.Context, delegate(BlockParam/*!*/ selfBlock, object _, object item) {
                if (result == Missing.Value) {
                    result = item;
                    return null;
                }

                if (operation == null) {
                    throw RubyExceptions.NoBlockGiven();
                }

                if (operation.Yield(result, item, out result)) {
                    return result;
                }

                return null;
            }));

            return result != Missing.Value ? result : null;
        }
Beispiel #20
0
        public static RubyArray Grep(CallSiteStorage<EachSite>/*!*/ each, BinaryOpStorage/*!*/ caseEquals, 
            BlockParam action, object self, object pattern) {

            RubyArray result = new RubyArray();
            var site = caseEquals.GetCallSite("===");

            Each(each, self, Proc.Create(each.Context, delegate(BlockParam/*!*/ selfBlock, object _, object item) {
                if (RubyOps.IsTrue(site.Target(site, pattern, item))) {
                    if (action != null) {
                        if (action.Yield(item, out item)) {
                            return item;
                        }
                    }
                    result.Add(item);
                }
                return null;
            }));

            return result;
        }
Beispiel #21
0
        private static RubyArray/*!*/ Filter(CallSiteStorage<EachSite>/*!*/ each, BlockParam predicate, object self, bool acceptingValue) {
            RubyArray result = new RubyArray();

            Each(each, self, Proc.Create(each.Context, delegate(BlockParam/*!*/ selfBlock, object _, object item) {
                if (predicate == null) {
                    throw RubyExceptions.NoBlockGiven();
                }

                object blockResult;
                if (predicate.Yield(item, out blockResult)) {
                    return blockResult;
                }

                // Check if the result is what we expect (use true to select, false to reject)
                if (Protocols.IsTrue(blockResult) == acceptingValue) {
                    result.Add(item);
                }
                return null;
            }));

            return result;
        }
Beispiel #22
0
 public static object InvokeOpenBlock(UnaryOpStorage/*!*/ closeStorage, BlockParam block, object obj) {
     object result = obj;
     if (!RubyOps.IsRetrySingleton(obj) && block != null) {
         try {
             block.Yield(obj, out result);
         } finally {
             try {
                 var site = closeStorage.GetCallSite("close");
                 site.Target(site, obj);                        
             } catch (SystemException) {
                 // MRI: nop
             }
         }
     }
     return result;
 }
Beispiel #23
0
        internal static object TryInvokeOpenBlock(RubyContext/*!*/ context, BlockParam/*!*/ block, RubyIO/*!*/ io) {
            if (block == null)
                return io;

            using (io) {
                object result;
                block.Yield(io, out result);
                return result;
            }
        }
Beispiel #24
0
        public static object EachByte(BlockParam block, RubyIO/*!*/ self) {
            self.RequireReadable();
            object aByte;
            while ((aByte = Getc(self)) != null) {
                if (block == null) {
                    throw RubyExceptions.NoBlockGiven();
                }

                object result;
                if (block.Yield((int)aByte, out result)) {
                    return result;
                }
            }
            return self;
        }
Beispiel #25
0
        // returns true if block jumped
        // "result" will be null if there is no successful match
        private static bool BlockReplaceFirst(RubyScope/*!*/ scope, MutableString/*!*/ input, BlockParam/*!*/ block,
            RubyRegex/*!*/ pattern, out object blockResult, out MutableString result) {

            var matchScope = scope.GetInnerMostClosureScope();
            MatchData match = RegexpOps.Match(scope, pattern, input);
            if (match == null || !match.Success) {
                result = null;
                blockResult = null;
                matchScope.CurrentMatch = null;
                return false;
            }

            // copy upfront so that no modifications to the input string are included in the result:
            result = input.Clone();
            matchScope.CurrentMatch = match;

            if (block.Yield(MutableString.Create(match.Value), out blockResult)) {
                return true;
            }

            // resets the $~ scope variable to the last match (skipd if block jumped):
            matchScope.CurrentMatch = match;

            MutableString replacement = Protocols.ConvertToString(scope.RubyContext, blockResult);
            result.TaintBy(replacement);

            // Note - we don't interpolate special sequences like \1 in block return value
            result.Replace(match.Index, match.Length, replacement);

            blockResult = null;
            return false;
        }
Beispiel #26
0
        public static RubyArray/*!*/ Zip(CallSiteStorage<EachSite>/*!*/ each, ConversionStorage<IList>/*!*/ tryToA, BlockParam block,
            object self, [NotNull]params object[] args) {
            RubyArray results = (block == null) ? new RubyArray() : null;

            // Call to_a on each argument
            IList[] otherArrays = new IList[args.Length];
            for (int i = 0; i < args.Length; i++) {
                otherArrays[i] = Protocols.TryConvertToArray(tryToA, args[i]);
            }

            int index = 0;
            Each(each, self, Proc.Create(each.Context, delegate(BlockParam/*!*/ selfBlock, object _, object item) {
                // Collect items
                RubyArray array = new RubyArray(otherArrays.Length + 1);
                array.Add(item);
                foreach (IList otherArray in otherArrays) {
                    if (index < otherArray.Count) {
                        array.Add(otherArray[index]);
                    } else {
                        array.Add(null);
                    }
                }

                index += 1;

                if (block != null) {
                    object blockResult;
                    if (block.Yield(array, out blockResult)) {
                        return blockResult;
                    }
                } else {
                    results.Add(array);
                }
                return null;
            }));

            return results;
        }
Beispiel #27
0
        // returns true if block jumped
        // "result" will be null if there is no successful match
        private static bool BlockReplaceAll(RubyScope/*!*/ scope, MutableString/*!*/ input, BlockParam/*!*/ block,
            RubyRegex/*!*/ regex, out object blockResult, out MutableString result) {

            var matchScope = scope.GetInnerMostClosureScope();

            MatchCollection matches = regex.Matches(input);
            if (matches.Count == 0) {
                result = null;
                blockResult = null;
                matchScope.CurrentMatch = null;
                return false;
            }

            // create an empty result:
            result = input.CreateInstance().TaintBy(input);
            
            int offset = 0;
            foreach (Match match in matches) {
                MatchData currentMatch = new MatchData(match, input);
                matchScope.CurrentMatch = currentMatch;

                uint version = input.Version;
                if (block.Yield(MutableString.Create(match.Value), out blockResult)) {
                    return true;
                }
                if (input.Version != version) {
                    return false;
                }

                // resets the $~ scope variable to the last match (skipd if block jumped):
                matchScope.CurrentMatch = currentMatch;

                MutableString replacement = Protocols.ConvertToString(scope.RubyContext, blockResult);
                result.TaintBy(replacement);

                // prematch:
                result.Append(input, offset, match.Index - offset);

                // replacement (unlike ReplaceAll, don't interpolate special sequences like \1 in block return value):
                result.Append(replacement);

                offset = match.Index + match.Length;
            }

            // post-last-match:
            result.Append(input, offset, input.Length - offset);

            blockResult = null;
            return false;
        }
Beispiel #28
0
        public static object EachWithIndex(CallSiteStorage<EachSite>/*!*/ each, BlockParam/*!*/ block, object self) {
            // for some reason each_with_index always checks for a block, even if there's nothing to yield
            if (block == null) {
                throw RubyExceptions.NoBlockGiven();
            }

            int index = 0;

            Each(each, self, Proc.Create(each.Context, delegate(BlockParam/*!*/ selfBlock, object _, object item) {
                object blockResult;
                if (block.Yield(item, index, out blockResult)) {
                    return blockResult;
                }
                index += 1;
                return null;
            }));

            return self;
        }
Beispiel #29
0
        public static object Find(CallSiteStorage<EachSite>/*!*/ each, CallSiteStorage<Func<CallSite, object, object>>/*!*/ callStorage,
            BlockParam predicate, object self, [Optional]object ifNone) {
            object result = Missing.Value;

            Each(each, self, Proc.Create(each.Context, delegate(BlockParam/*!*/ selfBlock, object _, object item) {
                if (predicate == null) {
                    throw RubyExceptions.NoBlockGiven();
                }

                object blockResult;
                if (predicate.Yield(item, out blockResult)) {
                    result = blockResult;
                    return selfBlock.Break(blockResult);
                }

                if (Protocols.IsTrue(blockResult)) {
                    result = item;
                    return selfBlock.Break(item);
                }

                return null;
            }));

            if (result == Missing.Value) {
                if (ifNone == Missing.Value || ifNone == null) {
                    return null;
                }

                var site = callStorage.GetCallSite("call", 0);
                result = site.Target(site, ifNone);
            }
            return result;
        }
Beispiel #30
0
        public static object Each(RubyContext/*!*/ context, BlockParam block, RubyIO/*!*/ self, [DefaultProtocol]MutableString separator, [DefaultProtocol]int limit) {
            self.RequireReadable();

            MutableString line;
            while ((line = self.ReadLineOrParagraph(separator, limit)) != null) {
                if (block == null) {
                    throw RubyExceptions.NoBlockGiven();
                }

                line.IsTainted = true;
                context.InputProvider.LastInputLineNumber = ++self.LineNumber;

                object result;
                if (block.Yield(line, out result)) {
                    return result;
                }
            }

            return self;
        }