I think that you got it right. negate
is a class method which returns a block.
That returned block takes an UnderscoreTestBlock
argument and returns another UnderscoreTestBlock
. Example:
UnderscoreTestBlock isANumber = ^BOOL (id obj) {
return [obj isKindOfClass:[NSNumber class]];
};
BOOL b1 = isANumber(@123); // YES
BOOL b2 = isANumber(@"abc"); // NO
UnderscoreTestBlock isNotANumber = [Underscore negate](isANumber);
BOOL b3 = isNotANumber(@123); // NO
BOOL b4 = isNotANumber(@"abc"); // YES
[Underscore negate]
returns a block that is called with the isANumber
argument.
The return value of that call is the block
^BOOL (id obj) { return !test(obj); };
where test
is the isANumber
argument, which is captured by the block.
I am sure that there are good reasons why the Underscore project defines the negate
method like this, it is probably necessary for their "functional" notation.
Otherwise a slightly simpler way would be to define a method
+ (UnderscoreTestBlock)negateBlock:(UnderscoreTestBlock)test
{
return ^BOOL (id obj) {
return !test(obj);
};
}
which would be used like
UnderscoreTestBlock isNotANumber = [Underscore negateBlock:isANumber];