Skip to content

Commit

Permalink
Convert between uint indexes and objects if rqrd.
Browse files Browse the repository at this point in the history
  • Loading branch information
mxcl committed Mar 10, 2014
1 parent c17b416 commit bb0d8c4
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 19 deletions.
25 changes: 18 additions & 7 deletions NSArray+Ruby.m
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#import "YOLO.h"
#import <objc/runtime.h>
extern int YOLOArgCount(id);
extern NSMethodSignature *YOLOMS(id);

/**
The blockToUse variable is necessary or: EXC_BAD_ACCESS
Expand All @@ -22,7 +23,6 @@
return [NSArray arrayWithObjects:selected count:ii]



@implementation NSArray (RubyEnumerable)

- (NSArray *(^)(id))select {
Expand All @@ -39,16 +39,27 @@ @implementation NSArray (RubyEnumerable)

- (NSArray *(^)(id))each {
return ^(id frock) {
if (YOLOArgCount(frock) == 3) {
void (^block)(id, NSUInteger) = frock;
NSUInteger ii = 0;
for (id obj in self)
block(obj, ii++);
} else {
NSMethodSignature *sig = YOLOMS(frock);
switch (sig.numberOfArguments) {
case 2: {
void (^block)(id) = frock;
for (id obj in self)
block(obj);
break;
}
case 3: {
void (^block)(id, NSUInteger) = frock;

if ([sig getArgumentTypeAtIndex:2][0] == '@')
block = ^(id o, NSUInteger ii) {
((void (^)(id, id))frock)(o, @(ii));
};

NSUInteger ii = 0;
for (id obj in self)
block(obj, ii++);
break;
}}
return self;
};
}
Expand Down
32 changes: 22 additions & 10 deletions README.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,6 @@ id rv = @[@1, @2, @3, @4].map(^(NSNumber *n){
return @(n.intValue * n.intValue);
});
// rv => @[@1, @4, @9, @16]

id rv = @[@1, @2, @3, @4].map(^(NSNumber *n, uint ii){
return @(n.intValue * ii);
});
// rv => @[@0, @2, @6, @12]
```

Notably, if you return nil, we skip that element in the returned array.
Expand All @@ -72,9 +67,27 @@ Justification:
2. We could add NSNull instead, but then we’d be crashy and *YOLOKit is forgiving*
3. In Objective-C calling a method on nil returns nil. When enumerating an array this is equivalent to just skipping that element. Hence: we skip the element.

```objc
id rv = @[@1, @2, @3, @4].map(^(NSNumber *n, uint ii){
return @(n.intValue * ii);
});
// rv => @[@0, @2, @6, @12]
```

YOLOKit can see how many arguments are in your block.

```objc
id rv = @[@1, @2, @3, @4].map(^(NSNumber *n, NSNumber *index){
return @{index: n};
});
// rv => @[@{@0: @1}, @{@1: @2}, @{@2: @3}, @{@3: @4}]
```

YOLOKit will convert between types for you depending on your block arguments.

###NSArray.select()
```objc
id rv = @[@1, @2, @3, @4].select(^BOOL(NSNumber *n){
id rv = @[@1, @2, @3, @4].select(^(NSNumber *n){
return n.intValue % 2 == 0;
});
// rv => @[@2, @4]
Expand All @@ -86,7 +99,7 @@ id rv = @[@1, @2, @3, @4].select(^BOOL(NSNumber *n){

###NSArray.reject()
```objc
id rv = @[@1, @2, @3, @4].reject(^BOOL(NSNumber *n){
id rv = @[@1, @2, @3, @4].reject(^(NSNumber *n){
return n.intValue % 2 == 0;
});
// rv => @[@1, @3]
Expand Down Expand Up @@ -251,7 +264,6 @@ id rv = @[@2, @1, @3, @5, @4].sort;
id rv = @[@"20", @"1", @3, @5, @"4"].sort;
// rv => @[@"1", @3, @"4", @5, @"20"] // handles mixed object types
```

###NSArray.pluck()
Expand Down Expand Up @@ -413,12 +425,12 @@ clear and reads more easily than `isEmpty`. Small wins add up.

###NSArray.all()
```objc
BOOL rv = @[@1, @2, @3].all(^BOOL(id o){
BOOL rv = @[@1, @2, @3].all(^(id o){
return [o intValue] > 0;
});
// rv => YES

BOOL rv = @[@1, @2, @3].all(^BOOL(id o){
BOOL rv = @[@1, @2, @3].all(^(id o){
return [o intValue] < 3;
});
// rv => NO
Expand Down
8 changes: 6 additions & 2 deletions YOLO.m
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
CTBlockDescriptionFlagsHasSignature = (1 << 30)
};

int YOLOArgCount(id block) {
NSMethodSignature *YOLOMS(id block) {
struct CTBlockLiteral *blockRef = (__bridge struct CTBlockLiteral *)block;
enum CTBlockDescriptionFlags flags = blockRef->flags;

Expand All @@ -54,7 +54,11 @@ int YOLOArgCount(id block) {
}

const char *signature = (*(const char **)signatureLocation);
return [NSMethodSignature signatureWithObjCTypes:signature].numberOfArguments;
return [NSMethodSignature signatureWithObjCTypes:signature];
}
return 0;
}

int YOLOArgCount(id block) {
return YOLOMS(block).numberOfArguments;
}
4 changes: 4 additions & 0 deletions tests
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,10 @@ int main() {
@[@1, @2, @3].each(^(id o, int ii){
XCTAssertEqualObjects(o, @(ii+1));
});
@[@0, @1, @2].each(^(id o, id ii){
XCTAssertEqualObjects(o, ii);
});
}
- (void)testSelect {
Expand Down

0 comments on commit bb0d8c4

Please sign in to comment.