Daniele Alessandri
2009-Jul-19 09:29 UTC
[Ironruby-core] Code review: String#unpack, Bignum and Array related stuff
Hi first of all I am trying a different approach to submitting my patches: I created a code_review branch on my repository in which I am going to push all my fixes for review. Fixes that will pass review will be rebased (not merged) in my main branch (ready to get pulled into the ironruby repository), the others will remain staged in my code_review branch for further works until they are "approved". I am just experimenting a different git workflow :-) Anyway, let''s move on to the new commits: * http://github.com/nrk/ironruby/commit/48a4a02b5b47d61f2f7a3f3887ea4bf02d63edb4 - More fixes for String#unpack: o Fixed errors when unpacking data with ''Z'' and ''@'' directives o Implemented ''Q'' and ''q'' directives * http://github.com/nrk/ironruby/commit/17b5edab64967b0200370edf6657321a0f79953d - Array related fixes: o Array#== does not call #to_ary on its argument but it calls #to_a (it basically performs a conversion of the argument rather than casting it to a ruby array) o Array#zip calls #to_ary to cast the argument to an Array, therefore it overrides Enumerable#zip in which the argument is converted by calling #to_a. * http://github.com/nrk/ironruby/commit/547d810c78b38afc34e728855ab7d0c20f499719 - Bignum related fixes: o Changed the signature for ClrBigInteger.ToString(self,radix), now Bignum#to_s works as expected raising an ArgumentException if base is less than 2 or higher than 36. o Fixed Bignum#divmod, Bignum#remainder, Bignum#% and Bignum#modulo to work with Float values as argument. o Fixed Bignum#/ and Bignum#div as they behave differently with each other when Float values are passed as argument. Note: Now bignum does not fail any of the expectations in core/bignum. See also the attached diff. Thanks, Daniele -- Daniele Alessandri http://www.clorophilla.net/blog/ http://twitter.com/JoL1hAHN -------------- next part -------------- diff --git a/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/array/equal_value_tags.txt b/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/array/equal_value_tags.txt index bf03ad0..17d97a5 100644 --- a/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/array/equal_value_tags.txt +++ b/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/array/equal_value_tags.txt @@ -1,2 +1 @@ fails:Array#== returns true if corresponding elements are #=-fails:Array#== does not call #to_ary on its argument diff --git a/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/array/zip_tags.txt b/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/array/zip_tags.txt deleted file mode 100644 index f863d32..0000000 --- a/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/array/zip_tags.txt +++ /dev/null @@ -1 +0,0 @@ -fails:Array#zip calls #to_ary to convert the argument to an Array diff --git a/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/bignum/div_tags.txt b/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/bignum/div_tags.txt deleted file mode 100644 index a4b2900..0000000 --- a/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/bignum/div_tags.txt +++ /dev/null @@ -1,2 +0,0 @@ -fails:Bignum#div returns a result of integer division of self by a float argument -fails:Bignum#div raises FloatDomainError if the argument is a float zero diff --git a/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/bignum/divmod_tags.txt b/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/bignum/divmod_tags.txt deleted file mode 100644 index f8a72c1..0000000 --- a/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/bignum/divmod_tags.txt +++ /dev/null @@ -1 +0,0 @@ -fails:Bignum#divmod returns an Array containing quotient and modulus obtained from dividing self by the given argument diff --git a/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/bignum/modulo_tags.txt b/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/bignum/modulo_tags.txt deleted file mode 100644 index d64c330..0000000 --- a/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/bignum/modulo_tags.txt +++ /dev/null @@ -1,2 +0,0 @@ -fails:Bignum#% returns the modulus obtained from dividing self by the given argument -fails:Bignum#modulo returns the modulus obtained from dividing self by the given argument diff --git a/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/bignum/remainder_tags.txt b/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/bignum/remainder_tags.txt deleted file mode 100644 index 0867179..0000000 --- a/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/bignum/remainder_tags.txt +++ /dev/null @@ -1 +0,0 @@ -fails:Bignum#remainder returns the remainder of dividing self by other diff --git a/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/bignum/to_s_tags.txt b/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/bignum/to_s_tags.txt deleted file mode 100644 index d14bd59..0000000 --- a/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/bignum/to_s_tags.txt +++ /dev/null @@ -1 +0,0 @@ -fails:Bignum#to_s when given a base raises an ArgumentError if the base is less than 2 or higher than 36 diff --git a/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/string/unpack_tags.txt b/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/string/unpack_tags.txt index d0ab5e9..0e5968d 100644 --- a/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/string/unpack_tags.txt +++ b/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/string/unpack_tags.txt @@ -1,14 +1,9 @@ fails:String#unpack returns an array by decoding self according to the format string -fails:String#unpack with ''Z'' directive returns an array by decoding self according to the format string fails:String#unpack with ''N'' and ''n'' directives returns an array by decoding self according to the format string -fails:String#unpack with ''Q'' and ''q'' directives returns an array in little-endian (native format) order by decoding self according to the format string -fails:String#unpack with ''Q'' and ''q'' directives returns Bignums for big numeric values on little-endian platforms -fails:String#unpack with ''Q'' and ''q'' directives returns Fixnums for small numeric values fails:String#unpack with ''a'', ''X'' and ''x'' directives returns an array by decoding self according to the format string fails:String#unpack with ''DdEeFfGg'' directives returns an array by decoding self according to the format string fails:String#unpack with ''DdEeFfGg'' directives returns an array by decoding self in little-endian order according to the format string fails:String#unpack with ''U'' directive returns an array by decoding self according to the format string -fails:String#unpack with ''@'' directive returns an array by decoding self according to the format string fails:String#unpack with ''M'' directive returns an array by decoding self according to the format string fails:String#unpack with ''m'' directive returns an array by decoding self according to the format string fails:String#unpack with ''w'' directive produces a BER-compressed integer diff --git a/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/ArrayOps.cs b/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/ArrayOps.cs index e2c3ee9..5f1c44c 100644 --- a/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/ArrayOps.cs +++ b/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/ArrayOps.cs @@ -215,34 +215,45 @@ namespace IronRuby.Builtins { if (!_native.TryGetValue(c, out tmp)) { throw RubyExceptions.CreateArgumentError("''_'' allowed only after types sSiIlL"); } c = tmp; i++; c2 = (i < format.Length) ? format[i] : ''\0''; } if (Char.IsDigit(c2)) { int pos1 = i; i++; while (i < format.Length && Char.IsDigit(format[i])) { i++; } count = Int32.Parse(format.Substring(pos1, (i - pos1))); i--; + } else if (c == ''@'' && c2 == ''-'') { + int pos1 = i; + i += 2; + while (i < format.Length && Char.IsDigit(format[i])) { + i++; + } + count = Int32.Parse(format.Substring(pos1, (i - pos1))); + i--; } else if (c2 == ''*'') { count = null; } else { i--; + if (c == ''@'') { + count = 0; + } } yield return new FormatDirective(c, count); } } } #endregion #region pack [RubyMethod("pack")] public static MutableString/*!*/ Pack( ConversionStorage<IntegerValue>/*!*/ integerConversion, ConversionStorage<MutableString>/*!*/ stringCast, diff --git a/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/MutableStringOps.cs b/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/MutableStringOps.cs index 06cec4b..c420cb8 100644 --- a/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/MutableStringOps.cs +++ b/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/MutableStringOps.cs @@ -2601,31 +2601,39 @@ namespace IronRuby.Builtins { } } [RubyMethod("unpack")] public static RubyArray/*!*/ Unpack(RubyContext/*!*/ context, MutableString/*!*/ self, [DefaultProtocol, NotNull]MutableString/*!*/ format) { RubyArray result = new RubyArray(1 + self.Length / 2); using (MutableStringStream stream = new MutableStringStream(self)) { BinaryReader reader = new BinaryReader(stream); foreach (ArrayOps.FormatDirective directive in ArrayOps.FormatDirective.Enumerate(format.ToString())) { int count, maxCount; byte[] buffer; MutableString str; int nilCount = 0; switch (directive.Directive) { case ''@'': - stream.Position = directive.Count.HasValue ? directive.Count.Value : stream.Position; + if (directive.Count.HasValue) { + if (directive.Count.Value > stream.Length) { + throw RubyExceptions.CreateArgumentError("@ outside of string"); + } + stream.Position = directive.Count.Value > 0 ? directive.Count.Value : 0; + } + else { + stream.Position = stream.Length; + } break; case ''A'': case ''a'': maxCount = (int)(stream.Length - stream.Position); count = directive.Count.HasValue ? directive.Count.Value : maxCount; if (count > maxCount) { count = maxCount; } buffer = reader.ReadBytes(count); str = MutableString.CreateBinary(buffer); if (directive.Directive == ''A'') { // TODO: efficiency? for (int pos = count - 1; pos >= 0; pos--) { if (buffer[pos] != 0 && buffer[pos] != 0x20) { @@ -2671,30 +2679,33 @@ namespace IronRuby.Builtins { } result.Add(str); break; case ''Z'': maxCount = (int)(stream.Length - stream.Position); count = directive.Count.HasValue ? directive.Count.Value : maxCount; if (count > maxCount) { count = maxCount; } buffer = reader.ReadBytes(count); str = MutableString.CreateBinary(buffer); for (int pos = 0; pos < count; pos++) { if (buffer[pos] == 0) { str.Remove(pos, count - pos); + if (!directive.Count.HasValue) { + stream.Seek(pos - count + 1, SeekOrigin.End); + } break; } } result.Add(str); break; case ''c'': count = CalculateCounts(stream, directive.Count, sizeof(sbyte), out nilCount); for (int j = 0; j < count; j++) { result.Add((int)reader.ReadSByte()); } break; case ''C'': count = CalculateCounts(stream, directive.Count, sizeof(byte), out nilCount); @@ -2743,30 +2754,79 @@ namespace IronRuby.Builtins { if (!BitConverter.IsLittleEndian) { value = (0x000000FF & (value >> 24) | 0x0000FF00 & (value >> 8) | 0x00FF0000 & (value << 8) | 0xFF000000 & (value << 24)); } if (value <= Int32.MaxValue) { result.Add((int)value); } else { result.Add((BigInteger)value); } } break; + case ''q'': + count = CalculateCounts(stream, directive.Count, sizeof(long), out nilCount); + for (int j = 0; j < count; j++) { + long value = reader.ReadInt64(); + if (!BitConverter.IsLittleEndian) { + ulong uvalue = (ulong)value; + uvalue = (0x00000000000000FF & (uvalue >> 56)) | + (0x000000000000FF00 & (uvalue >> 40)) | + (0x0000000000FF0000 & (uvalue >> 24)) | + (0x00000000FF000000 & (uvalue >> 8)) | + (0x000000FF00000000 & (uvalue << 8)) | + (0x0000FF0000000000 & (uvalue << 24)) | + (0x00FF000000000000 & (uvalue << 40)) | + (0xFF00000000000000 & (uvalue << 56)); + value = (long)uvalue; + } + if (value <= Int32.MaxValue && value >= Int32.MinValue) { + result.Add((int)value); + } + else { + result.Add((BigInteger)value); + } + } + break; + + case ''Q'': + count = CalculateCounts(stream, directive.Count, sizeof(ulong), out nilCount); + nilCount = 0; + for (int j = 0; j < count; j++) { + ulong value = reader.ReadUInt64(); + if (!BitConverter.IsLittleEndian) { + value = (0xFF00000000000000 & (value << 56)) | + (0x00FF000000000000 & (value >> 40)) | + (0x0000FF0000000000 & (value >> 24)) | + (0x000000FF00000000 & (value >> 8)) | + (0x00000000FF000000 & (value << 8)) | + (0x0000000000FF0000 & (value << 24)) | + (0x000000000000FF00 & (value << 40)) | + (0x00000000000000FF & (value << 56)); + } + if (value <= Int32.MaxValue) { + result.Add((int)value); + } + else { + result.Add((BigInteger)value); + } + } + break; + case ''m'': // TODO: Recognize "==" as end of base 64 encoding int len = (int)(stream.Length - stream.Position); char[] base64 = reader.ReadChars(len); byte[] data = Convert.FromBase64CharArray(base64, 0, len); result.Add(MutableString.CreateBinary(data)); break; case ''s'': count = CalculateCounts(stream, directive.Count, sizeof(short), out nilCount); for (int j = 0; j < count; j++) { result.Add((int)reader.ReadInt16()); } break; diff --git a/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Extensions/ClrBigInteger.cs b/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Extensions/ClrBigInteger.cs index 25a9fee..e1f5069 100644 --- a/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Extensions/ClrBigInteger.cs +++ b/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Extensions/ClrBigInteger.cs @@ -160,36 +160,45 @@ namespace IronRuby.Builtins { /// <summary> /// Divides self by other, where other is Bignum or Fixnum /// </summary> /// <returns>self / other</returns> /// <remarks>Uses DivMod to do the division (directly). Normalizes to a Fixnum if necessary</remarks> [RubyMethod("/"), RubyMethod("div")] public static object Divide(BigInteger/*!*/ self, [NotNull]BigInteger/*!*/ other) { return DivMod(self, other)[0]; } /// <summary> /// Divides self by other, where other is Float /// </summary> /// <returns>self / other as Float</returns> - [RubyMethod("/"), RubyMethod("div")] - public static object Divide(BigInteger/*!*/ self, double other) { + [RubyMethod("/")] + public static object DivideOp(BigInteger/*!*/ self, double other) { return self.ToFloat64() / other; } /// <summary> + /// Divides self by other, where other is Float + /// </summary> + /// <returns>self divided by other as Float</returns> + [RubyMethod("div")] + public static object Divide(BigInteger/*!*/ self, double other) { + return DivMod(self, other)[0]; + } + + /// <summary> /// Divides self by other, where other is not a Float, Fixnum or Bignum /// </summary> /// <returns>self / other</returns> /// <remarks>Coerces self and other using other.coerce(self) then dynamically invokes /</remarks> [RubyMethod("/")] public static object Divide(BinaryOpStorage/*!*/ coercionStorage, BinaryOpStorage/*!*/ binaryOpSite, object/*!*/ self, object other) { return Protocols.CoerceAndApply(coercionStorage, binaryOpSite, "/", self, other); } /// <summary> /// Divides self by other, where other is not a Float, Fixnum or Bignum /// </summary> /// <returns>self.div(other)</returns> /// <remarks>Coerces self and other using other.coerce(self) then dynamically invokes div</remarks> [RubyMethod("div")] @@ -288,30 +297,44 @@ namespace IronRuby.Builtins { #region modulo, % /// <summary> /// Returns self modulo other, where other is Fixnum or Bignum. /// </summary> /// <returns>self modulo other, as Fixnum or Bignum</returns> /// <remarks>Calls divmod directly to get the modulus.</remarks> [RubyMethod("%"), RubyMethod("modulo")] public static object Modulo(BigInteger/*!*/ self, [NotNull]BigInteger/*!*/ other) { RubyArray result = DivMod(self, other); return result[1]; } /// <summary> + /// Returns self modulo other, where other is Float. + /// </summary> + /// <returns>self modulo other, as Float</returns> + /// <remarks>Calls divmod directly to get the modulus.</remarks> + [RubyMethod("%"), RubyMethod("modulo")] + public static object Modulo(BigInteger/*!*/ self, double other) { + if (other == 0.0) { + return Double.NaN; + } + RubyArray result = DivMod(self, other); + return result[1]; + } + + /// <summary> /// Returns self % other, where other is not Fixnum or Bignum. /// </summary> /// <returns>self % other, as Fixnum or Bignum</returns> /// <remarks>Coerces self and other using other.coerce(self) then dynamically invokes %</remarks> [RubyMethod("%")] public static object ModuloOp(BinaryOpStorage/*!*/ coercionStorage, BinaryOpStorage/*!*/ binaryOpSite, object/*!*/ self, object other) { return Protocols.CoerceAndApply(coercionStorage, binaryOpSite, "%", self, other); } /// <summary> /// Returns self modulo other, where other is not Fixnum or Bignum. /// </summary> /// <returns>self modulo other, as Fixnum or Bignum</returns> /// <remarks>Coerces self and other using other.coerce(self) then dynamically invokes modulo</remarks> [RubyMethod("modulo")] @@ -331,30 +354,51 @@ namespace IronRuby.Builtins { /// </summary> /// <returns>[self div other, self modulo other] as RubyArray</returns> /// <remarks>Normalizes div and mod to Fixnum as necessary</remarks> [RubyMethod("divmod")] public static RubyArray DivMod(BigInteger/*!*/ self, [NotNull]BigInteger/*!*/ other) { BigInteger mod; BigInteger div = BigInteger.DivRem(self, other, out mod); if (self.Sign != other.Sign && !mod.IsZero()) { div = div - 1; mod = mod + other; } return RubyOps.MakeArray2(Protocols.Normalize(div), Protocols.Normalize(mod)); } /// <summary> + /// Returns an array containing the quotient and modulus obtained by dividing self by other, where other is Float. + /// If <code>q, r = x.divmod(y)</code>, then + /// <code>q = floor(float(x)/float(y))</code> + /// <code>x = q*y + r</code> + /// </summary> + /// <returns>[self div other, self modulo other] as RubyArray</returns> + /// <remarks>Normalizes div to Fixnum as necessary</remarks> + [RubyMethod("divmod")] + public static RubyArray DivMod(BigInteger/*!*/ self, double other) { + if (other == 0.0) { + throw new FloatDomainError("NaN"); + } + + double selfFloat = self.ToFloat64(); + BigInteger div = BigInteger.Create(selfFloat / other); + double mod = selfFloat % other; + + return RubyOps.MakeArray2(Protocols.Normalize(div), mod); + } + + /// <summary> /// Returns an array containing the quotient and modulus obtained by dividing self by other, where other is not Fixnum or Bignum. /// If <code>q, r = x.divmod(y)</code>, then /// <code>q = floor(float(x)/float(y))</code> /// <code>x = q*y + r</code> /// </summary> /// <returns>Should return [self div other, self modulo other], but the divmod implementation is free to return an arbitrary object.</returns> /// <remarks>Coerces self and other using other.coerce(self) then dynamically invokes divmod</remarks> [RubyMethod("divmod")] public static object DivMod(BinaryOpStorage/*!*/ coercionStorage, BinaryOpStorage/*!*/ binaryOpSite, object/*!*/ self, object other) { return Protocols.CoerceAndApply(coercionStorage, binaryOpSite, "divmod", self, other); } #endregion #region remainder @@ -362,36 +406,48 @@ namespace IronRuby.Builtins { /// <summary> /// Returns the remainder after dividing self by other, where other is Fixnum or Bignum. /// </summary> /// <example> /// -1234567890987654321.remainder(13731) #=> -6966 /// </example> /// <returns>Fixnum or Bignum</returns> [RubyMethod("remainder")] public static object Remainder(BigInteger/*!*/ self, [NotNull]BigInteger/*!*/ other) { BigInteger remainder; BigInteger.DivRem(self, other, out remainder); return Protocols.Normalize(remainder); } /// <summary> - /// Returns the remainder after dividing self by other, where other is not Fixnum or Bignum. + /// Returns the remainder after dividing self by other, where other is Float. /// </summary> /// <example> /// -1234567890987654321.remainder(13731.24) #=> -9906.22531493148 /// </example> - /// <returns>Float, Fixnum or Bignum</returns> + /// <returns>Float</returns> + [RubyMethod("remainder")] + public static double Remainder(BigInteger/*!*/ self, double other) { + return self.ToFloat64() % other; + } + + /// <summary> + /// Returns the remainder after dividing self by other, where other is not Fixnum or Bignum. + /// </summary> + /// <example> + /// -1234567890987654321.remainder(13731) #=> -6966 + /// </example> + /// <returns>Fixnum or Bignum</returns> /// <remarks>Coerces self and other using other.coerce(self) then dynamically invokes remainder</remarks> [RubyMethod("remainder")] public static object Remainder(BinaryOpStorage/*!*/ coercionStorage, BinaryOpStorage/*!*/ binaryOpSite, object/*!*/ self, object other) { return Protocols.CoerceAndApply(coercionStorage, binaryOpSite, "remainder", self, other); } #endregion #endregion #region Comparisons #region <=> /// <summary> @@ -750,31 +806,31 @@ namespace IronRuby.Builtins { #region to_s /// <summary> /// Returns a string containing the representation of self base 10. /// </summary> [RubyMethod("to_s")] public static MutableString/*!*/ ToString(BigInteger/*!*/ self) { return MutableString.Create(self.ToString()); } /// <summary> /// Returns a string containing the representation of self base radix (2 through 36). /// </summary> /// <param name="radix">An integer between 2 and 36 inclusive</param> [RubyMethod("to_s")] - public static MutableString/*!*/ ToString(BigInteger/*!*/ self, uint radix) { + public static MutableString/*!*/ ToString(BigInteger/*!*/ self, int radix) { if (radix < 2 || radix > 36) { throw RubyExceptions.CreateArgumentError(String.Format("illegal radix {0}", radix)); } // TODO: Can we do the ToLower in BigInteger? return MutableString.Create(self.ToString((uint)radix).ToLower()); } #endregion #region coerce /// <summary> /// Attempts to coerce other to a Bignum. /// </summary> diff --git a/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Extensions/IListOps.cs b/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Extensions/IListOps.cs index 9ed59b8..ce53a97 100644 --- a/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Extensions/IListOps.cs +++ b/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Extensions/IListOps.cs @@ -15,30 +15,32 @@ using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using Microsoft.Scripting; using Microsoft.Scripting.Generation; using Microsoft.Scripting.Runtime; using Microsoft.Scripting.Utils; using IronRuby.Runtime; using IronRuby.Runtime.Calls; +using EachSite = System.Func<System.Runtime.CompilerServices.CallSite, object, IronRuby.Builtins.Proc, object>; + namespace IronRuby.Builtins { [RubyModule(Extends = typeof(IList), Restrictions = ModuleRestrictions.None)] [Includes(typeof(Enumerable))] public static class IListOps { #region Helpers // MRI: Some operations check frozen flag even if they don''t change the array content. private static void RequireNotFrozen(IList/*!*/ self) { RubyArray array = self as RubyArray; if (array != null && array.IsFrozen) { throw RubyExceptions.CreateObjectFrozenError(); } } @@ -290,32 +292,32 @@ namespace IronRuby.Builtins { internal static int IndexOf(CallSite<Func<CallSite, object, object, object>>/*!*/ equalitySite, IList/*!*/ self, object item) { for (int i = 0; i < self.Count; i++) { if (Protocols.IsTrue(equalitySite.Target(equalitySite, item, self[i]))) { return i; } } return -1; } #endregion #region ==, <=>, eql?, hash [RubyMethod("==")] - public static bool Equals(ConversionStorage<IList>/*!*/ arrayTryCast, BinaryOpStorage/*!*/ equals, IList/*!*/ self, object other) { - IList otherAsArray = Protocols.TryCastToArray(arrayTryCast, other); + public static bool Equals(ConversionStorage<IList>/*!*/ arrayTryConvert, BinaryOpStorage/*!*/ equals, IList/*!*/ self, object other) { + IList otherAsArray = Protocols.TryConvertToArray(arrayTryConvert, other); return otherAsArray != null ? Equals(equals, self, otherAsArray) : false; } [MultiRuntimeAware] private static RubyUtils.RecursionTracker _EqualsTracker = new RubyUtils.RecursionTracker(); [RubyMethod("==")] public static bool Equals(BinaryOpStorage/*!*/ equals, IList/*!*/ self, [NotNull]IList/*!*/ other) { Assert.NotNull(self, other); if (object.ReferenceEquals(self, other)) { return true; } if (self.Count != other.Count) { @@ -1521,17 +1523,32 @@ namespace IronRuby.Builtins { seen.Add(key, true); i++; } else if (key == null && !nilSeen) { nilSeen = true; i++; } else { self.RemoveAt(i); modified = true; } } return modified ? self : null; } #endregion + + #region zip + + [RubyMethod("zip")] + public static IList/*!*/ Zip(CallSiteStorage<EachSite>/*!*/ each, ConversionStorage<IList>/*!*/ tryToAry, BlockParam block, + object self, [NotNull]params object[] args) { + + IList[] otherArrays = new IList[args.Length]; + for (int i = 0; i < args.Length; i++) { + otherArrays[i] = args[i] as IList != null ? args[i] as IList : Protocols.TryCastToArray(tryToAry, args[i]); + } + return Enumerable.Zip(each, tryToAry, block, self, otherArrays); + } + + #endregion } } diff --git a/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Initializers.Generated.cs b/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Initializers.Generated.cs index 1fa3d06..c2dea59 100644 --- a/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Initializers.Generated.cs +++ b/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Initializers.Generated.cs @@ -1870,55 +1870,56 @@ namespace IronRuby.Builtins { new System.Func<IronRuby.Runtime.RubyContext, System.Object, IronRuby.Builtins.Hash>(IronRuby.Builtins.IronRubyOps.ClrOps.GetProfile), new System.Func<IronRuby.Runtime.RubyContext, IronRuby.Runtime.BlockParam, System.Object, System.Object>(IronRuby.Builtins.IronRubyOps.ClrOps.GetProfile) ); } private static void LoadIronRuby__Clr__BigInteger_Instance(IronRuby.Builtins.RubyModule/*!*/ module) { module.DefineLibraryMethod("-", 0x51, new System.Func<Microsoft.Scripting.Math.BigInteger, Microsoft.Scripting.Math.BigInteger, System.Object>(IronRuby.Builtins.ClrBigInteger.Subtract), new System.Func<Microsoft.Scripting.Math.BigInteger, System.Double, System.Object>(IronRuby.Builtins.ClrBigInteger.Subtract), new System.Func<IronRuby.Runtime.BinaryOpStorage, IronRuby.Runtime.BinaryOpStorage, System.Object, System.Object, System.Object>(IronRuby.Builtins.ClrBigInteger.Subtract) ); module.DefineLibraryMethod("%", 0x51, new System.Func<Microsoft.Scripting.Math.BigInteger, Microsoft.Scripting.Math.BigInteger, System.Object>(IronRuby.Builtins.ClrBigInteger.Modulo), + new System.Func<Microsoft.Scripting.Math.BigInteger, System.Double, System.Object>(IronRuby.Builtins.ClrBigInteger.Modulo), new System.Func<IronRuby.Runtime.BinaryOpStorage, IronRuby.Runtime.BinaryOpStorage, System.Object, System.Object, System.Object>(IronRuby.Builtins.ClrBigInteger.ModuloOp) ); module.DefineLibraryMethod("&", 0x51, new System.Func<Microsoft.Scripting.Math.BigInteger, System.Int32, System.Object>(IronRuby.Builtins.ClrBigInteger.And), new System.Func<Microsoft.Scripting.Math.BigInteger, Microsoft.Scripting.Math.BigInteger, System.Object>(IronRuby.Builtins.ClrBigInteger.And), new System.Func<IronRuby.Runtime.RubyContext, Microsoft.Scripting.Math.BigInteger, IronRuby.Runtime.IntegerValue, System.Object>(IronRuby.Builtins.ClrBigInteger.And) ); module.DefineLibraryMethod("*", 0x51, new System.Func<Microsoft.Scripting.Math.BigInteger, Microsoft.Scripting.Math.BigInteger, System.Object>(IronRuby.Builtins.ClrBigInteger.Multiply), new System.Func<Microsoft.Scripting.Math.BigInteger, System.Double, System.Object>(IronRuby.Builtins.ClrBigInteger.Multiply), new System.Func<IronRuby.Runtime.BinaryOpStorage, IronRuby.Runtime.BinaryOpStorage, System.Object, System.Object, System.Object>(IronRuby.Builtins.ClrBigInteger.Multiply) ); module.DefineLibraryMethod("**", 0x51, new System.Func<IronRuby.Runtime.RubyContext, Microsoft.Scripting.Math.BigInteger, Microsoft.Scripting.Math.BigInteger, System.Object>(IronRuby.Builtins.ClrBigInteger.Power), new System.Func<Microsoft.Scripting.Math.BigInteger, System.Int32, System.Object>(IronRuby.Builtins.ClrBigInteger.Power), new System.Func<Microsoft.Scripting.Math.BigInteger, System.Double, System.Object>(IronRuby.Builtins.ClrBigInteger.Power), new System.Func<IronRuby.Runtime.BinaryOpStorage, IronRuby.Runtime.BinaryOpStorage, System.Object, System.Object, System.Object>(IronRuby.Builtins.ClrBigInteger.Power) ); module.DefineLibraryMethod("/", 0x51, new System.Func<Microsoft.Scripting.Math.BigInteger, Microsoft.Scripting.Math.BigInteger, System.Object>(IronRuby.Builtins.ClrBigInteger.Divide), - new System.Func<Microsoft.Scripting.Math.BigInteger, System.Double, System.Object>(IronRuby.Builtins.ClrBigInteger.Divide), + new System.Func<Microsoft.Scripting.Math.BigInteger, System.Double, System.Object>(IronRuby.Builtins.ClrBigInteger.DivideOp), new System.Func<IronRuby.Runtime.BinaryOpStorage, IronRuby.Runtime.BinaryOpStorage, System.Object, System.Object, System.Object>(IronRuby.Builtins.ClrBigInteger.Divide) ); module.DefineLibraryMethod("-@", 0x51, new System.Func<Microsoft.Scripting.Math.BigInteger, System.Object>(IronRuby.Builtins.ClrBigInteger.Negate) ); module.DefineLibraryMethod("[]", 0x51, new System.Func<Microsoft.Scripting.Math.BigInteger, System.Int32, System.Int32>(IronRuby.Builtins.ClrBigInteger.Bit), new System.Func<Microsoft.Scripting.Math.BigInteger, Microsoft.Scripting.Math.BigInteger, System.Int32>(IronRuby.Builtins.ClrBigInteger.Bit) ); module.DefineLibraryMethod("^", 0x51, new System.Func<Microsoft.Scripting.Math.BigInteger, System.Int32, System.Object>(IronRuby.Builtins.ClrBigInteger.Xor), new System.Func<Microsoft.Scripting.Math.BigInteger, Microsoft.Scripting.Math.BigInteger, System.Object>(IronRuby.Builtins.ClrBigInteger.Xor), @@ -1970,66 +1971,69 @@ namespace IronRuby.Builtins { ); module.DefineLibraryMethod("coerce", 0x51, new System.Func<Microsoft.Scripting.Math.BigInteger, Microsoft.Scripting.Math.BigInteger, IronRuby.Builtins.RubyArray>(IronRuby.Builtins.ClrBigInteger.Coerce), new System.Func<IronRuby.Runtime.RubyContext, Microsoft.Scripting.Math.BigInteger, System.Object, IronRuby.Builtins.RubyArray>(IronRuby.Builtins.ClrBigInteger.Coerce) ); module.DefineLibraryMethod("div", 0x51, new System.Func<Microsoft.Scripting.Math.BigInteger, Microsoft.Scripting.Math.BigInteger, System.Object>(IronRuby.Builtins.ClrBigInteger.Divide), new System.Func<Microsoft.Scripting.Math.BigInteger, System.Double, System.Object>(IronRuby.Builtins.ClrBigInteger.Divide), new System.Func<IronRuby.Runtime.BinaryOpStorage, IronRuby.Runtime.BinaryOpStorage, System.Object, System.Object, System.Object>(IronRuby.Builtins.ClrBigInteger.Div) ); module.DefineLibraryMethod("divmod", 0x51, new System.Func<Microsoft.Scripting.Math.BigInteger, Microsoft.Scripting.Math.BigInteger, IronRuby.Builtins.RubyArray>(IronRuby.Builtins.ClrBigInteger.DivMod), + new System.Func<Microsoft.Scripting.Math.BigInteger, System.Double, IronRuby.Builtins.RubyArray>(IronRuby.Builtins.ClrBigInteger.DivMod), new System.Func<IronRuby.Runtime.BinaryOpStorage, IronRuby.Runtime.BinaryOpStorage, System.Object, System.Object, System.Object>(IronRuby.Builtins.ClrBigInteger.DivMod) ); module.DefineLibraryMethod("eql?", 0x51, new System.Func<Microsoft.Scripting.Math.BigInteger, Microsoft.Scripting.Math.BigInteger, System.Boolean>(IronRuby.Builtins.ClrBigInteger.Eql), new System.Func<Microsoft.Scripting.Math.BigInteger, System.Int32, System.Boolean>(IronRuby.Builtins.ClrBigInteger.Eql), new System.Func<Microsoft.Scripting.Math.BigInteger, System.Object, System.Boolean>(IronRuby.Builtins.ClrBigInteger.Eql) ); module.DefineLibraryMethod("hash", 0x51, new System.Func<Microsoft.Scripting.Math.BigInteger, System.Int32>(IronRuby.Builtins.ClrBigInteger.Hash) ); module.DefineLibraryMethod("modulo", 0x51, new System.Func<Microsoft.Scripting.Math.BigInteger, Microsoft.Scripting.Math.BigInteger, System.Object>(IronRuby.Builtins.ClrBigInteger.Modulo), + new System.Func<Microsoft.Scripting.Math.BigInteger, System.Double, System.Object>(IronRuby.Builtins.ClrBigInteger.Modulo), new System.Func<IronRuby.Runtime.BinaryOpStorage, IronRuby.Runtime.BinaryOpStorage, System.Object, System.Object, System.Object>(IronRuby.Builtins.ClrBigInteger.Modulo) ); module.DefineLibraryMethod("quo", 0x51, new System.Func<Microsoft.Scripting.Math.BigInteger, Microsoft.Scripting.Math.BigInteger, System.Object>(IronRuby.Builtins.ClrBigInteger.Quotient), new System.Func<Microsoft.Scripting.Math.BigInteger, System.Double, System.Object>(IronRuby.Builtins.ClrBigInteger.Quotient), new System.Func<IronRuby.Runtime.BinaryOpStorage, IronRuby.Runtime.BinaryOpStorage, System.Object, System.Object, System.Object>(IronRuby.Builtins.ClrBigInteger.Quotient) ); module.DefineLibraryMethod("remainder", 0x51, new System.Func<Microsoft.Scripting.Math.BigInteger, Microsoft.Scripting.Math.BigInteger, System.Object>(IronRuby.Builtins.ClrBigInteger.Remainder), + new System.Func<Microsoft.Scripting.Math.BigInteger, System.Double, System.Double>(IronRuby.Builtins.ClrBigInteger.Remainder), new System.Func<IronRuby.Runtime.BinaryOpStorage, IronRuby.Runtime.BinaryOpStorage, System.Object, System.Object, System.Object>(IronRuby.Builtins.ClrBigInteger.Remainder) ); module.DefineLibraryMethod("to_f", 0x51, new System.Func<IronRuby.Runtime.RubyContext, Microsoft.Scripting.Math.BigInteger, System.Double>(IronRuby.Builtins.ClrBigInteger.ToFloat) ); module.DefineLibraryMethod("to_s", 0x51, new System.Func<Microsoft.Scripting.Math.BigInteger, IronRuby.Builtins.MutableString>(IronRuby.Builtins.ClrBigInteger.ToString), - new System.Func<Microsoft.Scripting.Math.BigInteger, System.UInt32, IronRuby.Builtins.MutableString>(IronRuby.Builtins.ClrBigInteger.ToString) + new System.Func<Microsoft.Scripting.Math.BigInteger, System.Int32, IronRuby.Builtins.MutableString>(IronRuby.Builtins.ClrBigInteger.ToString) ); } private static void LoadIronRuby__Clr__FlagEnumeration_Instance(IronRuby.Builtins.RubyModule/*!*/ module) { module.DefineLibraryMethod("&", 0x51, new System.Func<IronRuby.Runtime.RubyContext, System.Object, System.Object, System.Object>(IronRuby.Builtins.FlagEnumOps.BitwiseAnd) ); module.DefineLibraryMethod("^", 0x51, new System.Func<IronRuby.Runtime.RubyContext, System.Object, System.Object, System.Object>(IronRuby.Builtins.FlagEnumOps.Xor) ); module.DefineLibraryMethod("|", 0x51, new System.Func<IronRuby.Runtime.RubyContext, System.Object, System.Object, System.Object>(IronRuby.Builtins.FlagEnumOps.BitwiseOr) @@ -5397,30 +5401,34 @@ namespace IronRuby.Builtins { ); module.DefineLibraryMethod("uniq!", 0x51, new System.Func<IronRuby.Runtime.UnaryOpStorage, IronRuby.Runtime.BinaryOpStorage, System.Collections.IList, System.Collections.IList>(IronRuby.Builtins.IListOps.UniqueSelf) ); module.DefineLibraryMethod("unshift", 0x51, new System.Func<System.Collections.IList, System.Object, System.Collections.IList>(IronRuby.Builtins.IListOps.Unshift), new System.Func<System.Collections.IList, System.Object[], System.Collections.IList>(IronRuby.Builtins.IListOps.Unshift) ); module.DefineLibraryMethod("values_at", 0x51, new System.Func<IronRuby.Runtime.ConversionStorage<System.Int32>, IronRuby.Runtime.CallSiteStorage<System.Func<System.Runtime.CompilerServices.CallSite, IronRuby.Builtins.RubyClass, System.Object>>, System.Collections.IList, System.Object[], IronRuby.Builtins.RubyArray>(IronRuby.Builtins.IListOps.ValuesAt) ); + module.DefineLibraryMethod("zip", 0x51, + new System.Func<IronRuby.Runtime.CallSiteStorage<System.Func<System.Runtime.CompilerServices.CallSite, System.Object, IronRuby.Builtins.Proc, System.Object>>, IronRuby.Runtime.ConversionStorage<System.Collections.IList>, IronRuby.Runtime.BlockParam, System.Object, System.Object[], System.Collections.IList>(IronRuby.Builtins.IListOps.Zip) + ); + } private static void LoadSystem__IComparable_Instance(IronRuby.Builtins.RubyModule/*!*/ module) { module.DefineLibraryMethod("<=>", 0x51, new System.Func<System.IComparable, System.Object, System.Int32>(IronRuby.Builtins.IComparableOps.Compare) ); } private static void LoadSystem__Int16_Instance(IronRuby.Builtins.RubyModule/*!*/ module) { LoadIronRuby__Clr__Integer_Instance(module); module.DefineLibraryMethod("size", 0x51, new System.Func<System.Int16, System.Int32>(IronRuby.Builtins.Int16Ops.Size) );
Daniele Alessandri
2009-Jul-22 20:51 UTC
[Ironruby-core] Code review: String#unpack, Bignum and Array related stuff
Just a quick note: updated with http://github.com/nrk/ironruby/commit/82feca718fc17ad45747ca45a1c92250abfcfce0 On Sun, Jul 19, 2009 at 11:29, Daniele Alessandri<suppakilla at gmail.com> wrote:> Hi > first of all I am trying a different approach to submitting my > patches: I created a code_review branch on my repository in which I am > going to push all my fixes for review. Fixes that will pass review > will be rebased (not merged) in my main branch (ready to get pulled > into the ironruby repository), the others will remain staged in my > code_review branch for further works until they are "approved". I am > just experimenting a different git workflow :-) > > Anyway, let''s move on to the new commits: > > > * http://github.com/nrk/ironruby/commit/48a4a02b5b47d61f2f7a3f3887ea4bf02d63edb4 > > - More fixes for String#unpack: > ? o Fixed errors when unpacking data with ''Z'' and ''@'' directives > ? o Implemented ''Q'' and ''q'' directives > > > * http://github.com/nrk/ironruby/commit/17b5edab64967b0200370edf6657321a0f79953d > > - Array related fixes: > ? o Array#== does not call #to_ary on its argument but it calls #to_a (it > ? basically performs a conversion of the argument rather than casting it to a > ? ruby array) > ? o Array#zip calls #to_ary to cast the argument to an Array, therefore it > ? overrides Enumerable#zip in which the argument is converted by calling > ? #to_a. > > > * http://github.com/nrk/ironruby/commit/547d810c78b38afc34e728855ab7d0c20f499719 > > - Bignum related fixes: > ? o Changed the signature for ClrBigInteger.ToString(self,radix), now > ? Bignum#to_s works as expected raising an ArgumentException if base is less > ? than 2 or higher than 36. > ? o Fixed Bignum#divmod, Bignum#remainder, Bignum#% and Bignum#modulo to work > ? with Float values as argument. > ? o Fixed Bignum#/ and Bignum#div as they behave differently with each other > ? when Float values are passed as argument. > > Note: Now bignum does not fail any of the expectations in core/bignum. > > See also the attached diff. > > Thanks, > Daniele-- Daniele Alessandri http://www.clorophilla.net/blog/ http://twitter.com/JoL1hAHN
Shri Borde
2009-Jul-22 21:51 UTC
[Ironruby-core] Code review: String#unpack, Bignum and Array related stuff
Looks good. In Array#zip, you prefer casting to IList, and use Protocols.TryCastToArray as a fallback. Is that correct? If an IList object defines to_a, shouldn''t to_a get called? The array argument to Array#zip is marked as [NotNull]. Should it also be marked as [NotNullItems]? Thanks, Shri -----Original Message----- From: ironruby-core-bounces at rubyforge.org [mailto:ironruby-core-bounces at rubyforge.org] On Behalf Of Daniele Alessandri Sent: Wednesday, July 22, 2009 1:51 PM To: ironruby-core at rubyforge.org Subject: Re: [Ironruby-core] Code review: String#unpack, Bignum and Array related stuff Just a quick note: updated with http://github.com/nrk/ironruby/commit/82feca718fc17ad45747ca45a1c92250abfcfce0 On Sun, Jul 19, 2009 at 11:29, Daniele Alessandri<suppakilla at gmail.com> wrote:> Hi > first of all I am trying a different approach to submitting my > patches: I created a code_review branch on my repository in which I am > going to push all my fixes for review. Fixes that will pass review > will be rebased (not merged) in my main branch (ready to get pulled > into the ironruby repository), the others will remain staged in my > code_review branch for further works until they are "approved". I am > just experimenting a different git workflow :-) > > Anyway, let''s move on to the new commits: > > > * http://github.com/nrk/ironruby/commit/48a4a02b5b47d61f2f7a3f3887ea4bf02d63edb4 > > - More fixes for String#unpack: > ? o Fixed errors when unpacking data with ''Z'' and ''@'' directives > ? o Implemented ''Q'' and ''q'' directives > > > * http://github.com/nrk/ironruby/commit/17b5edab64967b0200370edf6657321a0f79953d > > - Array related fixes: > ? o Array#== does not call #to_ary on its argument but it calls #to_a (it > ? basically performs a conversion of the argument rather than casting it to a > ? ruby array) > ? o Array#zip calls #to_ary to cast the argument to an Array, therefore it > ? overrides Enumerable#zip in which the argument is converted by calling > ? #to_a. > > > * http://github.com/nrk/ironruby/commit/547d810c78b38afc34e728855ab7d0c20f499719 > > - Bignum related fixes: > ? o Changed the signature for ClrBigInteger.ToString(self,radix), now > ? Bignum#to_s works as expected raising an ArgumentException if base is less > ? than 2 or higher than 36. > ? o Fixed Bignum#divmod, Bignum#remainder, Bignum#% and Bignum#modulo to work > ? with Float values as argument. > ? o Fixed Bignum#/ and Bignum#div as they behave differently with each other > ? when Float values are passed as argument. > > Note: Now bignum does not fail any of the expectations in core/bignum. > > See also the attached diff. > > Thanks, > Daniele-- Daniele Alessandri http://www.clorophilla.net/blog/ http://twitter.com/JoL1hAHN _______________________________________________ Ironruby-core mailing list Ironruby-core at rubyforge.org http://rubyforge.org/mailman/listinfo/ironruby-core
Tomas Matousek
2009-Jul-22 22:25 UTC
[Ironruby-core] Code review: String#unpack, Bignum and Array related stuff
Actually, wouldn''t public static IList/*!*/ Zip(CallSiteStorage<EachSite>/*!*/ each, ConversionStorage<IList>/*!*/ tryToAry, BlockParam block, object self, [DefaultProtocol, NotNull, NotNullItems]params IList[] args) { work? If [DefaultProtocol] is applied on a params array of IList it converts all parameters to IList via to_ary method. Also Enumerable.Zip should be split into 2 methods: one that performs to_a conversion on all object args and other (internal) strongly typed method that takes IList[] and performs no conversions. IList.zip should then call the latter so that to_a conversions are not performed unnecessarily on already converted values. This is what I tested in MRI: class C def respond_to? name puts name true end def to_ary [1] end def to_a [2] end end class D include Enumerable def each 1 end end [1,2,3].zip(C.new, C.new, C.new) #=> to_ary, to_ary, to_ary D.new.zip(C.new, C.new, C.new) #=> to_a, to_a, to_a Tomas -----Original Message----- From: ironruby-core-bounces at rubyforge.org [mailto:ironruby-core-bounces at rubyforge.org] On Behalf Of Shri Borde Sent: Wednesday, July 22, 2009 2:52 PM To: ironruby-core at rubyforge.org Subject: Re: [Ironruby-core] Code review: String#unpack, Bignum and Array related stuff Looks good. In Array#zip, you prefer casting to IList, and use Protocols.TryCastToArray as a fallback. Is that correct? If an IList object defines to_a, shouldn''t to_a get called? The array argument to Array#zip is marked as [NotNull]. Should it also be marked as [NotNullItems]? Thanks, Shri -----Original Message----- From: ironruby-core-bounces at rubyforge.org [mailto:ironruby-core-bounces at rubyforge.org] On Behalf Of Daniele Alessandri Sent: Wednesday, July 22, 2009 1:51 PM To: ironruby-core at rubyforge.org Subject: Re: [Ironruby-core] Code review: String#unpack, Bignum and Array related stuff Just a quick note: updated with http://github.com/nrk/ironruby/commit/82feca718fc17ad45747ca45a1c92250abfcfce0 On Sun, Jul 19, 2009 at 11:29, Daniele Alessandri<suppakilla at gmail.com> wrote:> Hi > first of all I am trying a different approach to submitting my > patches: I created a code_review branch on my repository in which I am > going to push all my fixes for review. Fixes that will pass review > will be rebased (not merged) in my main branch (ready to get pulled > into the ironruby repository), the others will remain staged in my > code_review branch for further works until they are "approved". I am > just experimenting a different git workflow :-) > > Anyway, let''s move on to the new commits: > > > * > http://github.com/nrk/ironruby/commit/48a4a02b5b47d61f2f7a3f3887ea4bf0 > 2d63edb4 > > - More fixes for String#unpack: > o Fixed errors when unpacking data with ''Z'' and ''@'' directives > o Implemented ''Q'' and ''q'' directives > > > * > http://github.com/nrk/ironruby/commit/17b5edab64967b0200370edf6657321a > 0f79953d > > - Array related fixes: > o Array#== does not call #to_ary on its argument but it calls #to_a (it > basically performs a conversion of the argument rather than casting it to a > ruby array) > o Array#zip calls #to_ary to cast the argument to an Array, therefore it > overrides Enumerable#zip in which the argument is converted by calling > #to_a. > > > * > http://github.com/nrk/ironruby/commit/547d810c78b38afc34e728855ab7d0c2 > 0f499719 > > - Bignum related fixes: > o Changed the signature for ClrBigInteger.ToString(self,radix), now > Bignum#to_s works as expected raising an ArgumentException if base is less > than 2 or higher than 36. > o Fixed Bignum#divmod, Bignum#remainder, Bignum#% and Bignum#modulo to work > with Float values as argument. > o Fixed Bignum#/ and Bignum#div as they behave differently with each other > when Float values are passed as argument. > > Note: Now bignum does not fail any of the expectations in core/bignum. > > See also the attached diff. > > Thanks, > Daniele-- Daniele Alessandri http://www.clorophilla.net/blog/ http://twitter.com/JoL1hAHN _______________________________________________ Ironruby-core mailing list Ironruby-core at rubyforge.org http://rubyforge.org/mailman/listinfo/ironruby-core _______________________________________________ Ironruby-core mailing list Ironruby-core at rubyforge.org http://rubyforge.org/mailman/listinfo/ironruby-core
Daniele Alessandri
2009-Jul-23 18:38 UTC
[Ironruby-core] Code review: String#unpack, Bignum and Array related stuff
Hi, Cool I didn''t know [DefaultProtocol] was valid for params arguments too. I fixed the code and pushed it to GitHub, here is the commit: http://github.com/nrk/ironruby/commit/00a9a22440ad243eabfd4795788261f2d7ce12cd If it''s OK, I can rebase everything into my master branch to get it ready for tomorrow''s pull. Thanks, Daniele On Thu, Jul 23, 2009 at 00:25, Tomas Matousek<Tomas.Matousek at microsoft.com> wrote:> Actually, wouldn''t > > public static IList/*!*/ Zip(CallSiteStorage<EachSite>/*!*/ each, ConversionStorage<IList>/*!*/ tryToAry, BlockParam block, ?object self, [DefaultProtocol, NotNull, NotNullItems]params IList[] args) { > > work? If [DefaultProtocol] is applied on a params array of IList it converts all parameters to IList via to_ary method. > > Also Enumerable.Zip should be split into 2 methods: one that performs to_a conversion on all object args and other (internal) strongly typed method that takes IList[] and performs no conversions. > IList.zip should then call the latter so that to_a conversions are not performed unnecessarily on already converted values. > > This is what I tested in MRI: > > class C > ?def respond_to? name > ? ?puts name > ? ?true > ?end > > ?def to_ary > ? ?[1] > ?end > > ?def to_a > ? ?[2] > ?end > end > > class D > ?include Enumerable > > ?def each > ? ?1 > ?end > end > > [1,2,3].zip(C.new, C.new, C.new) #=> to_ary, to_ary, to_ary > D.new.zip(C.new, C.new, C.new) #=> to_a, to_a, to_a > > Tomas > > -----Original Message----- > From: ironruby-core-bounces at rubyforge.org [mailto:ironruby-core-bounces at rubyforge.org] On Behalf Of Shri Borde > Sent: Wednesday, July 22, 2009 2:52 PM > To: ironruby-core at rubyforge.org > Subject: Re: [Ironruby-core] Code review: String#unpack, Bignum and Array related stuff > > Looks good. In Array#zip, you prefer casting to IList, and use Protocols.TryCastToArray as a fallback. Is that correct? If an IList object defines to_a, shouldn''t to_a get called? > > The array argument to Array#zip is marked as [NotNull]. Should it also be marked as [NotNullItems]? > > Thanks, > Shri > > > -----Original Message----- > From: ironruby-core-bounces at rubyforge.org [mailto:ironruby-core-bounces at rubyforge.org] On Behalf Of Daniele Alessandri > Sent: Wednesday, July 22, 2009 1:51 PM > To: ironruby-core at rubyforge.org > Subject: Re: [Ironruby-core] Code review: String#unpack, Bignum and Array related stuff > > Just a quick note: updated with > http://github.com/nrk/ironruby/commit/82feca718fc17ad45747ca45a1c92250abfcfce0 > > On Sun, Jul 19, 2009 at 11:29, Daniele Alessandri<suppakilla at gmail.com> wrote: >> Hi >> first of all I am trying a different approach to submitting my >> patches: I created a code_review branch on my repository in which I am >> going to push all my fixes for review. Fixes that will pass review >> will be rebased (not merged) in my main branch (ready to get pulled >> into the ironruby repository), the others will remain staged in my >> code_review branch for further works until they are "approved". I am >> just experimenting a different git workflow :-) >> >> Anyway, let''s move on to the new commits: >> >> >> * >> http://github.com/nrk/ironruby/commit/48a4a02b5b47d61f2f7a3f3887ea4bf0 >> 2d63edb4 >> >> - More fixes for String#unpack: >> ? o Fixed errors when unpacking data with ''Z'' and ''@'' directives >> ? o Implemented ''Q'' and ''q'' directives >> >> >> * >> http://github.com/nrk/ironruby/commit/17b5edab64967b0200370edf6657321a >> 0f79953d >> >> - Array related fixes: >> ? o Array#== does not call #to_ary on its argument but it calls #to_a (it >> ? basically performs a conversion of the argument rather than casting it to a >> ? ruby array) >> ? o Array#zip calls #to_ary to cast the argument to an Array, therefore it >> ? overrides Enumerable#zip in which the argument is converted by calling >> ? #to_a. >> >> >> * >> http://github.com/nrk/ironruby/commit/547d810c78b38afc34e728855ab7d0c2 >> 0f499719 >> >> - Bignum related fixes: >> ? o Changed the signature for ClrBigInteger.ToString(self,radix), now >> ? Bignum#to_s works as expected raising an ArgumentException if base is less >> ? than 2 or higher than 36. >> ? o Fixed Bignum#divmod, Bignum#remainder, Bignum#% and Bignum#modulo to work >> ? with Float values as argument. >> ? o Fixed Bignum#/ and Bignum#div as they behave differently with each other >> ? when Float values are passed as argument. >> >> Note: Now bignum does not fail any of the expectations in core/bignum. >> >> See also the attached diff. >> >> Thanks, >> Daniele > > > -- > Daniele Alessandri > http://www.clorophilla.net/blog/ > http://twitter.com/JoL1hAHN > _______________________________________________ > Ironruby-core mailing list > Ironruby-core at rubyforge.org > http://rubyforge.org/mailman/listinfo/ironruby-core > _______________________________________________ > Ironruby-core mailing list > Ironruby-core at rubyforge.org > http://rubyforge.org/mailman/listinfo/ironruby-core > _______________________________________________ > Ironruby-core mailing list > Ironruby-core at rubyforge.org > http://rubyforge.org/mailman/listinfo/ironruby-core >-- Daniele Alessandri http://www.clorophilla.net/blog/ http://twitter.com/JoL1hAHN
Tomas Matousek
2009-Jul-23 19:25 UTC
[Ironruby-core] Code review: String#unpack, Bignum and Array related stuff
Looks good. Tomas -----Original Message----- From: ironruby-core-bounces at rubyforge.org [mailto:ironruby-core-bounces at rubyforge.org] On Behalf Of Daniele Alessandri Sent: Thursday, July 23, 2009 11:38 AM To: ironruby-core at rubyforge.org Subject: Re: [Ironruby-core] Code review: String#unpack, Bignum and Array related stuff Hi, Cool I didn''t know [DefaultProtocol] was valid for params arguments too. I fixed the code and pushed it to GitHub, here is the commit: http://github.com/nrk/ironruby/commit/00a9a22440ad243eabfd4795788261f2d7ce12cd If it''s OK, I can rebase everything into my master branch to get it ready for tomorrow''s pull. Thanks, Daniele On Thu, Jul 23, 2009 at 00:25, Tomas Matousek<Tomas.Matousek at microsoft.com> wrote:> Actually, wouldn''t > > public static IList/*!*/ Zip(CallSiteStorage<EachSite>/*!*/ each, > ConversionStorage<IList>/*!*/ tryToAry, BlockParam block, object > self, [DefaultProtocol, NotNull, NotNullItems]params IList[] args) { > > work? If [DefaultProtocol] is applied on a params array of IList it converts all parameters to IList via to_ary method. > > Also Enumerable.Zip should be split into 2 methods: one that performs to_a conversion on all object args and other (internal) strongly typed method that takes IList[] and performs no conversions. > IList.zip should then call the latter so that to_a conversions are not performed unnecessarily on already converted values. > > This is what I tested in MRI: > > class C > def respond_to? name > puts name > true > end > > def to_ary > [1] > end > > def to_a > [2] > end > end > > class D > include Enumerable > > def each > 1 > end > end > > [1,2,3].zip(C.new, C.new, C.new) #=> to_ary, to_ary, to_ary > D.new.zip(C.new, C.new, C.new) #=> to_a, to_a, to_a > > Tomas > > -----Original Message----- > From: ironruby-core-bounces at rubyforge.org > [mailto:ironruby-core-bounces at rubyforge.org] On Behalf Of Shri Borde > Sent: Wednesday, July 22, 2009 2:52 PM > To: ironruby-core at rubyforge.org > Subject: Re: [Ironruby-core] Code review: String#unpack, Bignum and > Array related stuff > > Looks good. In Array#zip, you prefer casting to IList, and use Protocols.TryCastToArray as a fallback. Is that correct? If an IList object defines to_a, shouldn''t to_a get called? > > The array argument to Array#zip is marked as [NotNull]. Should it also be marked as [NotNullItems]? > > Thanks, > Shri > > > -----Original Message----- > From: ironruby-core-bounces at rubyforge.org > [mailto:ironruby-core-bounces at rubyforge.org] On Behalf Of Daniele > Alessandri > Sent: Wednesday, July 22, 2009 1:51 PM > To: ironruby-core at rubyforge.org > Subject: Re: [Ironruby-core] Code review: String#unpack, Bignum and > Array related stuff > > Just a quick note: updated with > http://github.com/nrk/ironruby/commit/82feca718fc17ad45747ca45a1c92250 > abfcfce0 > > On Sun, Jul 19, 2009 at 11:29, Daniele Alessandri<suppakilla at gmail.com> wrote: >> Hi >> first of all I am trying a different approach to submitting my >> patches: I created a code_review branch on my repository in which I >> am going to push all my fixes for review. Fixes that will pass review >> will be rebased (not merged) in my main branch (ready to get pulled >> into the ironruby repository), the others will remain staged in my >> code_review branch for further works until they are "approved". I am >> just experimenting a different git workflow :-) >> >> Anyway, let''s move on to the new commits: >> >> >> * >> http://github.com/nrk/ironruby/commit/48a4a02b5b47d61f2f7a3f3887ea4bf >> 0 >> 2d63edb4 >> >> - More fixes for String#unpack: >> o Fixed errors when unpacking data with ''Z'' and ''@'' directives >> o Implemented ''Q'' and ''q'' directives >> >> >> * >> http://github.com/nrk/ironruby/commit/17b5edab64967b0200370edf6657321 >> a >> 0f79953d >> >> - Array related fixes: >> o Array#== does not call #to_ary on its argument but it calls #to_a (it >> basically performs a conversion of the argument rather than casting it to a >> ruby array) >> o Array#zip calls #to_ary to cast the argument to an Array, therefore it >> overrides Enumerable#zip in which the argument is converted by calling >> #to_a. >> >> >> * >> http://github.com/nrk/ironruby/commit/547d810c78b38afc34e728855ab7d0c >> 2 >> 0f499719 >> >> - Bignum related fixes: >> o Changed the signature for ClrBigInteger.ToString(self,radix), now >> Bignum#to_s works as expected raising an ArgumentException if base is less >> than 2 or higher than 36. >> o Fixed Bignum#divmod, Bignum#remainder, Bignum#% and Bignum#modulo to work >> with Float values as argument. >> o Fixed Bignum#/ and Bignum#div as they behave differently with each other >> when Float values are passed as argument. >> >> Note: Now bignum does not fail any of the expectations in core/bignum. >> >> See also the attached diff. >> >> Thanks, >> Daniele > > > -- > Daniele Alessandri > http://www.clorophilla.net/blog/ > http://twitter.com/JoL1hAHN > _______________________________________________ > Ironruby-core mailing list > Ironruby-core at rubyforge.org > http://rubyforge.org/mailman/listinfo/ironruby-core > _______________________________________________ > Ironruby-core mailing list > Ironruby-core at rubyforge.org > http://rubyforge.org/mailman/listinfo/ironruby-core > _______________________________________________ > Ironruby-core mailing list > Ironruby-core at rubyforge.org > http://rubyforge.org/mailman/listinfo/ironruby-core >-- Daniele Alessandri http://www.clorophilla.net/blog/ http://twitter.com/JoL1hAHN _______________________________________________ Ironruby-core mailing list Ironruby-core at rubyforge.org http://rubyforge.org/mailman/listinfo/ironruby-core
Daniele Alessandri
2009-Jul-23 19:48 UTC
[Ironruby-core] Code review: String#unpack, Bignum and Array related stuff
Thanks. Rebased and pushed to remote, my master branch on github is ready for tomorrow. Daniele On Thu, Jul 23, 2009 at 21:25, Tomas Matousek<Tomas.Matousek at microsoft.com> wrote:> Looks good. > > Tomas > > -----Original Message----- > From: ironruby-core-bounces at rubyforge.org [mailto:ironruby-core-bounces at rubyforge.org] On Behalf Of Daniele Alessandri > Sent: Thursday, July 23, 2009 11:38 AM > To: ironruby-core at rubyforge.org > Subject: Re: [Ironruby-core] Code review: String#unpack, Bignum and Array related stuff > > Hi, > > Cool I didn''t know [DefaultProtocol] was valid for params arguments too. > > I fixed the code and pushed it to GitHub, here is the commit: > http://github.com/nrk/ironruby/commit/00a9a22440ad243eabfd4795788261f2d7ce12cd > > If it''s OK, I can rebase everything into my master branch to get it ready for tomorrow''s pull. > > Thanks, > Daniele > > > On Thu, Jul 23, 2009 at 00:25, Tomas > Matousek<Tomas.Matousek at microsoft.com> wrote: >> Actually, wouldn''t >> >> public static IList/*!*/ Zip(CallSiteStorage<EachSite>/*!*/ each, >> ConversionStorage<IList>/*!*/ tryToAry, BlockParam block, ?object >> self, [DefaultProtocol, NotNull, NotNullItems]params IList[] args) { >> >> work? If [DefaultProtocol] is applied on a params array of IList it converts all parameters to IList via to_ary method. >> >> Also Enumerable.Zip should be split into 2 methods: one that performs to_a conversion on all object args and other (internal) strongly typed method that takes IList[] and performs no conversions. >> IList.zip should then call the latter so that to_a conversions are not performed unnecessarily on already converted values. >> >> This is what I tested in MRI: >> >> class C >> ?def respond_to? name >> ? ?puts name >> ? ?true >> ?end >> >> ?def to_ary >> ? ?[1] >> ?end >> >> ?def to_a >> ? ?[2] >> ?end >> end >> >> class D >> ?include Enumerable >> >> ?def each >> ? ?1 >> ?end >> end >> >> [1,2,3].zip(C.new, C.new, C.new) #=> to_ary, to_ary, to_ary >> D.new.zip(C.new, C.new, C.new) #=> to_a, to_a, to_a >> >> Tomas >> >> -----Original Message----- >> From: ironruby-core-bounces at rubyforge.org >> [mailto:ironruby-core-bounces at rubyforge.org] On Behalf Of Shri Borde >> Sent: Wednesday, July 22, 2009 2:52 PM >> To: ironruby-core at rubyforge.org >> Subject: Re: [Ironruby-core] Code review: String#unpack, Bignum and >> Array related stuff >> >> Looks good. In Array#zip, you prefer casting to IList, and use Protocols.TryCastToArray as a fallback. Is that correct? If an IList object defines to_a, shouldn''t to_a get called? >> >> The array argument to Array#zip is marked as [NotNull]. Should it also be marked as [NotNullItems]? >> >> Thanks, >> Shri >> >> >> -----Original Message----- >> From: ironruby-core-bounces at rubyforge.org >> [mailto:ironruby-core-bounces at rubyforge.org] On Behalf Of Daniele >> Alessandri >> Sent: Wednesday, July 22, 2009 1:51 PM >> To: ironruby-core at rubyforge.org >> Subject: Re: [Ironruby-core] Code review: String#unpack, Bignum and >> Array related stuff >> >> Just a quick note: updated with >> http://github.com/nrk/ironruby/commit/82feca718fc17ad45747ca45a1c92250 >> abfcfce0 >> >> On Sun, Jul 19, 2009 at 11:29, Daniele Alessandri<suppakilla at gmail.com> wrote: >>> Hi >>> first of all I am trying a different approach to submitting my >>> patches: I created a code_review branch on my repository in which I >>> am going to push all my fixes for review. Fixes that will pass review >>> will be rebased (not merged) in my main branch (ready to get pulled >>> into the ironruby repository), the others will remain staged in my >>> code_review branch for further works until they are "approved". I am >>> just experimenting a different git workflow :-) >>> >>> Anyway, let''s move on to the new commits: >>> >>> >>> * >>> http://github.com/nrk/ironruby/commit/48a4a02b5b47d61f2f7a3f3887ea4bf >>> 0 >>> 2d63edb4 >>> >>> - More fixes for String#unpack: >>> ? o Fixed errors when unpacking data with ''Z'' and ''@'' directives >>> ? o Implemented ''Q'' and ''q'' directives >>> >>> >>> * >>> http://github.com/nrk/ironruby/commit/17b5edab64967b0200370edf6657321 >>> a >>> 0f79953d >>> >>> - Array related fixes: >>> ? o Array#== does not call #to_ary on its argument but it calls #to_a (it >>> ? basically performs a conversion of the argument rather than casting it to a >>> ? ruby array) >>> ? o Array#zip calls #to_ary to cast the argument to an Array, therefore it >>> ? overrides Enumerable#zip in which the argument is converted by calling >>> ? #to_a. >>> >>> >>> * >>> http://github.com/nrk/ironruby/commit/547d810c78b38afc34e728855ab7d0c >>> 2 >>> 0f499719 >>> >>> - Bignum related fixes: >>> ? o Changed the signature for ClrBigInteger.ToString(self,radix), now >>> ? Bignum#to_s works as expected raising an ArgumentException if base is less >>> ? than 2 or higher than 36. >>> ? o Fixed Bignum#divmod, Bignum#remainder, Bignum#% and Bignum#modulo to work >>> ? with Float values as argument. >>> ? o Fixed Bignum#/ and Bignum#div as they behave differently with each other >>> ? when Float values are passed as argument. >>> >>> Note: Now bignum does not fail any of the expectations in core/bignum. >>> >>> See also the attached diff. >>> >>> Thanks, >>> Daniele >> >> >> -- >> Daniele Alessandri >> http://www.clorophilla.net/blog/ >> http://twitter.com/JoL1hAHN >> _______________________________________________ >> Ironruby-core mailing list >> Ironruby-core at rubyforge.org >> http://rubyforge.org/mailman/listinfo/ironruby-core >> _______________________________________________ >> Ironruby-core mailing list >> Ironruby-core at rubyforge.org >> http://rubyforge.org/mailman/listinfo/ironruby-core >> _______________________________________________ >> Ironruby-core mailing list >> Ironruby-core at rubyforge.org >> http://rubyforge.org/mailman/listinfo/ironruby-core >> > > > > -- > Daniele Alessandri > http://www.clorophilla.net/blog/ > http://twitter.com/JoL1hAHN > _______________________________________________ > Ironruby-core mailing list > Ironruby-core at rubyforge.org > http://rubyforge.org/mailman/listinfo/ironruby-core > _______________________________________________ > Ironruby-core mailing list > Ironruby-core at rubyforge.org > http://rubyforge.org/mailman/listinfo/ironruby-core >-- Daniele Alessandri http://www.clorophilla.net/blog/ http://twitter.com/JoL1hAHN