Skip to content

Commit

Permalink
* Array#first(n) and Array#last(n) on a subclass of Array should retu…
Browse files Browse the repository at this point in the history
…rn an instance of Array and not an instance of the subclass.

* The result of Array#compact must keep the tainted status of the source array.

* A block passed to Array#delete should be executed only if no element matches the given object

* Array#flatten returns subclass instance for Array subclasses

* Array#flatten does not call flatten on elements

* Array#fetch passes the original index argument object to the block, not the converted Integer
  • Loading branch information
nrk committed Apr 15, 2009
1 parent 23b77ff commit b754ddc
Show file tree
Hide file tree
Showing 8 changed files with 38 additions and 32 deletions.

This file was deleted.

@@ -1,2 +1 @@
fails:Array#delete removes elements that are #== to object
fails:Array#delete may be given a block that is executed if no element matches object

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

Expand Up @@ -572,6 +572,8 @@ public static class IListOps {
}
}

allocateStorage.Context.TaintObjectBy<IList>(result, self);

return result;
}

Expand Down Expand Up @@ -620,7 +622,7 @@ public static class IListOps {
public static object Delete(BinaryOpStorage/*!*/ equals, BlockParam block, IList/*!*/ self, object item) {
bool removed = Remove(equals, self, item);

if (block != null) {
if (!removed && block != null) {
object result;
block.Yield(out result);
return result;
Expand Down Expand Up @@ -732,24 +734,37 @@ public static class IListOps {
#region fetch

[RubyMethod("fetch")]
public static object Fetch(RubyContext/*!*/ context, BlockParam outOfRangeValueProvider, IList/*!*/ list, [DefaultProtocol]int index, [Optional]object defaultValue) {
int oldIndex = index;
if (InRangeNormalized(list, ref index)) {
return list[index];
public static object Fetch(
RespondToStorage/*!*/ respondToStorage,
CallSiteStorage<Func<CallSite, object, int>>/*!*/ toIntStorage,
BlockParam outOfRangeValueProvider,
IList/*!*/ list,
object/*!*/ index,
[Optional]object defaultValue) {

if (!Protocols.RespondTo(respondToStorage, index, "to_int")) {
throw RubyExceptions.CannotConvertTypeToTargetType(respondToStorage.Context, index, "Integer");
}

var toInt = toIntStorage.GetCallSite("to_int", 0);
int convertedIndex = toInt.Target(toInt, index);

if (InRangeNormalized(list, ref convertedIndex)) {
return list[convertedIndex];
}

if (outOfRangeValueProvider != null) {
if (defaultValue != Missing.Value) {
context.ReportWarning("block supersedes default value argument");
respondToStorage.Context.ReportWarning("block supersedes default value argument");
}

object result;
outOfRangeValueProvider.Yield(oldIndex, out result);
outOfRangeValueProvider.Yield(index, out result);
return result;
}

if (defaultValue == Missing.Value) {
throw RubyExceptions.CreateIndexError("index " + index + " out of array");
throw RubyExceptions.CreateIndexError("index " + convertedIndex + " out of array");
}
return defaultValue;
}
Expand Down Expand Up @@ -879,7 +894,7 @@ public static class IListOps {
}

count = count > self.Count ? self.Count : count;
return GetResultRange(allocateStorage, self, 0, count);
return RubyArray.Create(self as IList<object>, 0, count);
}

[RubyMethod("last")]
Expand All @@ -895,7 +910,7 @@ public static class IListOps {
}

count = count > self.Count ? self.Count : count;
return GetResultRange(allocateStorage, self, self.Count - count, count);
return RubyArray.Create(self as IList<object>, self.Count - count, count);
}

#endregion
Expand All @@ -906,12 +921,11 @@ public static class IListOps {
private static RubyUtils.RecursionTracker _infiniteFlattenTracker = new RubyUtils.RecursionTracker();

public static bool TryFlattenArray(
CallSiteStorage<Func<CallSite, IList, object>>/*!*/ flattenStorage,
CallSiteStorage<Func<CallSite, RubyClass, object>>/*!*/ allocateStorage,
ConversionStorage<IList>/*!*/ tryToAry,
IList list, out IList/*!*/ result) {

// TODO: create correct subclass of RubyArray rather than RubyArray directly
result = new RubyArray();
result = CreateResultArray(allocateStorage, list);

using (IDisposable handle = _infiniteFlattenTracker.TrackObject(list)) {
if (handle == null) {
Expand All @@ -922,14 +936,13 @@ public static class IListOps {
IList item = Protocols.TryCastToArray(tryToAry, list[i]);
if (item != null) {
flattened = true;
var flatten = flattenStorage.GetCallSite("flatten", 0);
IList flattenedList;

object flattenedItem = flatten.Target(flatten, item);
IList flattenedList = Protocols.TryCastToArray(tryToAry, flattenedItem);
TryFlattenArray(allocateStorage, tryToAry, item, out flattenedList);
if (flattenedList != null) {
AddRange(result, flattenedList);
} else {
result.Add(flattenedItem);
result.Add(item);
}
} else {
result.Add(list[i]);
Expand All @@ -941,21 +954,21 @@ public static class IListOps {

[RubyMethod("flatten")]
public static IList/*!*/ Flatten(
CallSiteStorage<Func<CallSite, IList, object>>/*!*/ flattenStorage,
CallSiteStorage<Func<CallSite, RubyClass, object>>/*!*/ allocateStorage,
ConversionStorage<IList>/*!*/ tryToAry,
RubyContext/*!*/ context, IList/*!*/ self) {
IList result;
TryFlattenArray(flattenStorage, tryToAry, self, out result);
TryFlattenArray(allocateStorage, tryToAry, self, out result);
return result;
}

[RubyMethod("flatten!")]
public static IList FlattenInPlace(
CallSiteStorage<Func<CallSite, IList, object>>/*!*/ flattenStorage,
CallSiteStorage<Func<CallSite, RubyClass, object>>/*!*/ allocateStorage,
ConversionStorage<IList>/*!*/ tryToAry,
RubyContext/*!*/ context, IList/*!*/ self) {
IList result;
if (!TryFlattenArray(flattenStorage, tryToAry, self, out result)) {
if (!TryFlattenArray(allocateStorage, tryToAry, self, out result)) {
return null;
}

Expand Down
Expand Up @@ -5071,7 +5071,7 @@ public sealed class BuiltinsLibraryInitializer : IronRuby.Builtins.LibraryInitia
);

module.DefineLibraryMethod("fetch", 0x51,
new System.Func<IronRuby.Runtime.RubyContext, IronRuby.Runtime.BlockParam, System.Collections.IList, System.Int32, System.Object, System.Object>(IronRuby.Builtins.IListOps.Fetch)
new System.Func<IronRuby.Runtime.RespondToStorage, IronRuby.Runtime.CallSiteStorage<System.Func<System.Runtime.CompilerServices.CallSite, System.Object, System.Int32>>, IronRuby.Runtime.BlockParam, System.Collections.IList, System.Object, System.Object, System.Object>(IronRuby.Builtins.IListOps.Fetch)
);

module.DefineLibraryMethod("fill", 0x51,
Expand All @@ -5091,11 +5091,11 @@ public sealed class BuiltinsLibraryInitializer : IronRuby.Builtins.LibraryInitia
);

module.DefineLibraryMethod("flatten", 0x51,
new System.Func<IronRuby.Runtime.CallSiteStorage<System.Func<System.Runtime.CompilerServices.CallSite, System.Collections.IList, System.Object>>, IronRuby.Runtime.ConversionStorage<System.Collections.IList>, IronRuby.Runtime.RubyContext, System.Collections.IList, System.Collections.IList>(IronRuby.Builtins.IListOps.Flatten)
new System.Func<IronRuby.Runtime.CallSiteStorage<System.Func<System.Runtime.CompilerServices.CallSite, IronRuby.Builtins.RubyClass, System.Object>>, IronRuby.Runtime.ConversionStorage<System.Collections.IList>, IronRuby.Runtime.RubyContext, System.Collections.IList, System.Collections.IList>(IronRuby.Builtins.IListOps.Flatten)
);

module.DefineLibraryMethod("flatten!", 0x51,
new System.Func<IronRuby.Runtime.CallSiteStorage<System.Func<System.Runtime.CompilerServices.CallSite, System.Collections.IList, System.Object>>, IronRuby.Runtime.ConversionStorage<System.Collections.IList>, IronRuby.Runtime.RubyContext, System.Collections.IList, System.Collections.IList>(IronRuby.Builtins.IListOps.FlattenInPlace)
new System.Func<IronRuby.Runtime.CallSiteStorage<System.Func<System.Runtime.CompilerServices.CallSite, IronRuby.Builtins.RubyClass, System.Object>>, IronRuby.Runtime.ConversionStorage<System.Collections.IList>, IronRuby.Runtime.RubyContext, System.Collections.IList, System.Collections.IList>(IronRuby.Builtins.IListOps.FlattenInPlace)
);

module.DefineLibraryMethod("hash", 0x51,
Expand Down

0 comments on commit b754ddc

Please sign in to comment.