Permalink
Browse files

Update Array#product to handle block parameters as per rubyspec

  • Loading branch information...
1 parent e92404b commit ede005c8840bfdd0fe9b3d0dc11c9bad5cd4a3a3 Orion Edwards [GGL] committed Feb 1, 2012
@@ -312,16 +312,20 @@ public static class IListOps {
}
[RubyMethod("product")]
- public static RubyArray/*!*/ Product(IList/*!*/ self, [DefaultProtocol, NotNullItems]params IList/*!*/[]/*!*/ arrays) {
+ public static IList/*!*/ Product(BlockParam block, IList/*!*/ self, [DefaultProtocol, NotNullItems]params IList/*!*/[]/*!*/ arrays) {
var result = new RubyArray();
+ object blockResult = null;
if (self.Count == 0) {
- return result;
+ return self;
}
int requiredCapacity = 1;
for (int i = 0; i < arrays.Length; i++) {
if (arrays[i].Count == 0) {
+ if (block != null) { // [1,2].product([]) should produce [], but [1,2].product([]){ } should produce [1,2] due to empty block
+ return self;
+ }
return result;
}
try {
@@ -330,13 +334,21 @@ public static class IListOps {
throw RubyExceptions.CreateRangeError("too big to product");
}
}
-
+
int[] indices = new int[1 + arrays.Length];
while (true) {
var current = new RubyArray(indices.Length);
for (int i = 0; i < indices.Length; i++) {
current[i] = GetNth(i, self, arrays)[indices[i]];
}
+
+ if (block != null) {
+ block.Yield(current, out blockResult);
+ if (blockResult == null) {
+ return self;
+ }
+ }
+
result.Add(current);
// increment indices:
@@ -8092,8 +8092,8 @@ public sealed class BuiltinsLibraryInitializer : IronRuby.Builtins.LibraryInitia
);
DefineLibraryMethod(module, "product", 0x51,
- 0x80010002U,
- new Func<System.Collections.IList, System.Collections.IList[], IronRuby.Builtins.RubyArray>(IronRuby.Builtins.IListOps.Product)
+ 0x80020004U,
+ new Func<IronRuby.Runtime.BlockParam, System.Collections.IList, System.Collections.IList[], System.Collections.IList>(IronRuby.Builtins.IListOps.Product)
);
DefineLibraryMethod(module, "push", 0x51,

0 comments on commit ede005c

Please sign in to comment.