예제 #1
0
        /// <summary>
        /// Step through a Range of Strings.
        /// </summary>
        /// <remarks>
        /// This method requires step to be a Fixnum.
        /// It uses a hybrid string comparison to prevent infinite loops and calls String#succ to get each item in the range.
        /// </remarks>
        private static object StepString(RubyContext /*!*/ context, BlockParam block, Range /*!*/ self, MutableString begin, MutableString end, int step)
        {
            CheckStep(step);
            object        result;
            MutableString item = begin;
            int           comp;

            while ((comp = Protocols.Compare(context, item, end)) < 0)
            {
                if (block == null)
                {
                    throw RubyExceptions.NoBlockGiven();
                }

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

                for (int i = 0; i < step; ++i)
                {
                    item = (MutableString)RubySites.Successor(context, item);
                }

                if (item.Length > end.Length)
                {
                    return(self);
                }
            }

            if (comp == 0 && !self.ExcludeEnd)
            {
                if (block == null)
                {
                    throw RubyExceptions.NoBlockGiven();
                }

                if (block.Yield(item, out result))
                {
                    return(result);
                }
            }
            return(self);
        }
예제 #2
0
        /// <summary>
        /// Step through a Range of objects that are not Numeric or String.
        /// </summary>
        private static object StepObject(RubyContext /*!*/ context, BlockParam block, Range /*!*/ self, object begin, object end, int step)
        {
            CheckStep(context, step);
            object item = begin, result;
            int    comp;

            while ((comp = Protocols.Compare(context, item, end)) < 0)
            {
                if (block == null)
                {
                    throw RubyExceptions.NoBlockGiven();
                }

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

                for (int i = 0; i < step; ++i)
                {
                    item = RubySites.Successor(context, item);
                }
            }
            if (comp == 0 && !self.ExcludeEnd)
            {
                if (block == null)
                {
                    throw RubyExceptions.NoBlockGiven();
                }

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