1

Is there a way to use blocks with the ternary operator in Objective-C?

I'm trying to do something like:

[self evaluate] ? ^{
    // do somethings
} : ^{
    // do something else
}
Oscar Swanros
  • 19,767
  • 5
  • 32
  • 48
  • 1
    In general stay away from ternary operators, they make the code hard to read. Code should be written to be clear, concise and easy to read by humans. – zaph May 21 '14 at 18:28
  • 1
    What is the goal of this? Do you wish to assign one of the two block to a variable? As written, your code snippet doesn't make any sense. – rmaddy May 21 '14 at 18:29
  • 3
    Have you tried the code you just posted? There's no reason why that shouldn't work. You would have to do something useful with the returned block of course. – Philippe Leybaert May 21 '14 at 18:29
  • 1
    I totally agree with Zaph, you can use the ternary operator for very short inline assignments, but for anything else it is just ugly. Just use an if in this case. – iCaramba May 21 '14 at 18:30
  • @PhilippeLeybaert, tried, Xcode throws an "Expression result unused" warning. – Oscar Swanros May 21 '14 at 18:31
  • @OscarSwanros: Yes, because the expression evaluates to a block, but you don't *call* that block. – Martin R May 21 '14 at 18:31
  • 1
    @OscarSwanros You get the error because what you are doing makes no sense. See my 1st comment. – rmaddy May 21 '14 at 18:31
  • @OscarSwanros That's why I said you have to do something useful with the block. See the answer by Logan for an example – Philippe Leybaert May 21 '14 at 18:34

1 Answers1

5

You're getting result unused because you don't assign your block at all

void (^someBlock)(void) = [self evaluate] ? ^{
    // do somethings
} : ^{
    // do something else
};

someBlock();

Update

As @MartinR pointed out, if you'd prefer to get even more convoluted, you could call the block in the ternary:

[self evaluate] ? ^{
    // do somethings
}() : ^{
    // do something else
}();

Update 2

The actual convolution @MartinR was suggesting:

([self evaluate] ? ^{
    // do somethings
} : ^{
    // do something else
})();

NOTE

As @zaph and @joshCaswell have pointed out in the comments, while this is technically correct (the best kind of correct) it is perhaps not the best practice. In the case of executing the block inline as mentioned in the updates, it is particularly strange as mentioned in the answer here.

Community
  • 1
  • 1
Logan
  • 52,262
  • 20
  • 99
  • 128
  • Getting a little convoluted, it this really a good idea? Better than an `if-else` statement? – zaph May 21 '14 at 18:33
  • 1
    @Zaph The question was if it is possible to use the ternary operator with blocks. It's probably not a very good coding practice but that's not really the point here. – Philippe Leybaert May 21 '14 at 18:36
  • 4
    You could even call the block without assigning it to variable (to make it more convoluted :-) – Martin R May 21 '14 at 18:36
  • I know this is not good practice, I was just curious how this would look like in code. – Oscar Swanros May 21 '14 at 18:40
  • 1
    @Logan, your update is actually what I was trying to get to. Thanks for clearing this out! :D – Oscar Swanros May 21 '14 at 18:41
  • 1
    Now the second and third expression in the ternary are not blocks anymore. What I meant is `( ... ? block1 : block2 )()`. – Martin R May 21 '14 at 18:42
  • 1
    @MartinR - ReUpdated cuz why the heck not! :) – Logan May 21 '14 at 18:44
  • 1
    This is technically correct, but it should be pointed out that there's [absolutely no sense in creating an inline block that's immediately called and not assigned to a variable](http://stackoverflow.com/questions/23596977/inline-block-with-return-type/23597255#23597255). – jscs May 21 '14 at 19:20