Skip to content
Browse files

Update implementation of Array[]= to check frozen before coercing arg…

…s, and change the error message to match MRI 1.9.2 (as per rubyspec)
  • Loading branch information...
1 parent 5a52d46 commit 510023a7fb623387b39ded2395794389315d405e Orion Edwards [GGL] committed Jan 5, 2012
View
38 Languages/Ruby/Libraries/Extensions/IListOps.cs
@@ -519,7 +519,7 @@ public static class IListOps {
return self[index] = value;
}
-
+
[RubyMethod("[]=")]
public static object SetElement(IList/*!*/ self, [DefaultProtocol]int index, object value) {
index = NormalizeIndexThrowIfNegative(self, index);
@@ -534,6 +534,21 @@ public static class IListOps {
}
[RubyMethod("[]=")]
+ public static object SetElement(ConversionStorage<IList>/*!*/ arrayTryCast, ConversionStorage<int> fixnumCast,
+ RubyArray/*!*/ self, object index, object length, object value) {
+
+ self.RequireNotFrozen(); // rubyspec says we must check for frozen before trying to coerce the index
+ return SetElement(arrayTryCast, self as IList, Protocols.CastToFixnum(fixnumCast, index), Protocols.CastToFixnum(fixnumCast, length), value);
+ }
+
+ [RubyMethod("[]=")]
+ public static object SetElement(ConversionStorage<IList>/*!*/ arrayTryCast, RubyArray/*!*/ self,
+ [DefaultProtocol]int index, [DefaultProtocol]int length, object value) {
+
+ return SetElement(arrayTryCast, self as IList, index, length, value);
+ }
+
+ [RubyMethod("[]=")]
public static object SetElement(ConversionStorage<IList>/*!*/ arrayTryCast, IList/*!*/ self,
[DefaultProtocol]int index, [DefaultProtocol]int length, object value) {
if (length < 0) {
@@ -584,11 +599,24 @@ public static class IListOps {
[RubyMethod("[]=")]
public static object SetElement(ConversionStorage<IList>/*!*/ arrayTryCast, ConversionStorage<int>/*!*/ fixnumCast,
- IList/*!*/ self, [NotNull]Range/*!*/ range, object value) {
+ RubyArray/*!*/ self, object rangeOrIndex, object value) {
- int start, count;
- RangeToStartAndCount(fixnumCast, range, self.Count, out start, out count);
- return SetElement(arrayTryCast, self, start, count, value);
+ self.RequireNotFrozen(); // rubyspec says we must check for frozen before trying to coerce the index
+ return SetElement(arrayTryCast, fixnumCast, self as IList, rangeOrIndex, value);
+ }
+
+ [RubyMethod("[]=")]
+ public static object SetElement(ConversionStorage<IList>/*!*/ arrayTryCast, ConversionStorage<int>/*!*/ fixnumCast,
+ IList/*!*/ self, object rangeOrIndex, object value) {
+
+ var range = rangeOrIndex as Range;
+ if (range == null) {
+ return SetElement(self, Protocols.CastToFixnum(fixnumCast, rangeOrIndex), value);
+ } else {
+ int start, count;
+ RangeToStartAndCount(fixnumCast, range, self.Count, out start, out count);
+ return SetElement(arrayTryCast, self, start, count, value);
+ }
}
private static void RangeToStartAndCount(ConversionStorage<int>/*!*/ fixnumCast, Range/*!*/ range, int length, out int start, out int count) {
View
7 Languages/Ruby/Libraries/Initializers.Generated.cs
@@ -7840,11 +7840,14 @@ public sealed class BuiltinsLibraryInitializer : IronRuby.Builtins.LibraryInitia
);
DefineLibraryMethod(module, "[]=", 0x51,
- 0x00010000U, 0x00010000U, 0x00060000U, 0x00000008U,
+ new[] { 0x00010000U, 0x00010000U, 0x00000000U, 0x00060000U, 0x00060000U, 0x00000000U, 0x00000000U},
new Func<IronRuby.Builtins.RubyArray, System.Int32, System.Object, System.Object>(IronRuby.Builtins.IListOps.SetElement),
new Func<System.Collections.IList, System.Int32, System.Object, System.Object>(IronRuby.Builtins.IListOps.SetElement),
+ new Func<IronRuby.Runtime.ConversionStorage<System.Collections.IList>, IronRuby.Runtime.ConversionStorage<System.Int32>, IronRuby.Builtins.RubyArray, System.Object, System.Object, System.Object, System.Object>(IronRuby.Builtins.IListOps.SetElement),
+ new Func<IronRuby.Runtime.ConversionStorage<System.Collections.IList>, IronRuby.Builtins.RubyArray, System.Int32, System.Int32, System.Object, System.Object>(IronRuby.Builtins.IListOps.SetElement),
new Func<IronRuby.Runtime.ConversionStorage<System.Collections.IList>, System.Collections.IList, System.Int32, System.Int32, System.Object, System.Object>(IronRuby.Builtins.IListOps.SetElement),
- new Func<IronRuby.Runtime.ConversionStorage<System.Collections.IList>, IronRuby.Runtime.ConversionStorage<System.Int32>, System.Collections.IList, IronRuby.Builtins.Range, System.Object, System.Object>(IronRuby.Builtins.IListOps.SetElement)
+ new Func<IronRuby.Runtime.ConversionStorage<System.Collections.IList>, IronRuby.Runtime.ConversionStorage<System.Int32>, IronRuby.Builtins.RubyArray, System.Object, System.Object, System.Object>(IronRuby.Builtins.IListOps.SetElement),
+ new Func<IronRuby.Runtime.ConversionStorage<System.Collections.IList>, IronRuby.Runtime.ConversionStorage<System.Int32>, System.Collections.IList, System.Object, System.Object, System.Object>(IronRuby.Builtins.IListOps.SetElement)
);
DefineLibraryMethod(module, "|", 0x51,
View
6 Languages/Ruby/Ruby/Builtins/RubyArray.cs
@@ -142,12 +142,12 @@ public RubyArray(IEnumerable/*!*/ items)
public void RequireNotFrozen() {
if ((_flags & IsFrozenFlag) != 0) {
// throw in a separate method to allow inlining of the current one
- ThrowObjectFrozenException();
+ ThrowArrayFrozenException();
}
}
- private static void ThrowObjectFrozenException() {
- throw RubyExceptions.CreateObjectFrozenError();
+ private static void ThrowArrayFrozenException() {
+ throw RubyExceptions.CreateArrayFrozenError();
}
private void Mutate() {
View
4 Languages/Ruby/Ruby/Runtime/RubyExceptions.cs
@@ -48,6 +48,10 @@ public static class RubyExceptions {
return CreateRuntimeError("can't modify frozen object");
}
+ public static Exception/*!*/ CreateArrayFrozenError() {
+ return CreateRuntimeError("can't modify frozen array");
+ }
+
public static Exception/*!*/ CreateTypeConversionError(string/*!*/ fromType, string/*!*/ toType) {
Assert.NotNull(fromType, toType);
return CreateTypeError("can't convert {0} into {1}", fromType, toType);

0 comments on commit 510023a

Please sign in to comment.
Something went wrong with that request. Please try again.