Assert with string argument not working as expected - objective-c

EDIT: The issue was with the assert as people pointed out below. Thanks for the help!
I have a enum set that i'm trying equate, but for some reason its not working.
Its declared like so:
typedef NS_ENUM(NSUInteger, ExUnitTypes) {
kuNilWorkUnit,
kuDistanceInMeters,
//end
kuUndefined
};
And i'm using it here:
+(NSString*) ExUnitDescription: (ExUnitTypes) exUnit
{
if (exUnit == kuNilWorkUnit)
{
assert("error with units");
}
///.... more stuff
}
Xcode isnt triggering my assert. EDIT: the assert is just for testing. i've used NSLog as well. The conditional isn't evaluating to true even though the value is clearly kuNilWorkUnit.
Does anyone have any suggestions or ideas of what i'm doing wrong?

You want to do this:
+(NSString*) ExUnitDescription: (ExUnitTypes) exUnit
{
assert(exUnit != kuNilWorkUnit);
///.... more stuff
}
This is because, assert only stops execution if the expression you pass to it is false. Since a string literal is always non-zero, it will never stop execution.
Now, since you are using Objective C and it also looks like you want to have a message associated with your assert, NSAssert would be preferable.
+(NSString*) ExUnitDescription: (ExUnitTypes) exUnit
{
NSAssert(exUnit != kuNilWorkUnit, #"error with units");
///.... more stuff
}

Related

What is the analogue of Mockito.verifyZeroInteractions(obj) in the Mockk library?

I want to switch to Mockk, but i cant find analogue of this method in Mockk
It doesn't work
verify (exactly = 0) { obj }
The way you are trying it, is missing the method or variable
verify (exactly = 0) { obj.something }
Using the exactly zero approach would require
confirmVerified(obj)
To be sure nothing else was called.
The exact equivalent would be:
verify { obj wasNot Called }

Pass no value to function with default parameters

I have this Kotlin function:
fun doSomething(user: User = defaultUser) {
//do something
}
and I call it from another place:
val user: User? = getUser()
if (user == null) {
doSomething()
} else {
doSomething(user)
}
Is it possible to improve this code? I think this "if/else" is a little bit messy. Is possible to do something like this?
doSomething(user ?: NoValue)
You can cut it down to user?.run(::doSomething) ?: doSomething() (if doSomething doesn't return null) but I don't know why you'd want to!
Honestly the if/else reads nice to me, stick it on one line without the braces and it's nice and compact. Unfortunately I don't think you can conditionally add parameters into a function call (and handling default parameters can get unnwieldy when you have a few).
I agree with #benjiii, it might be better to have a nullable parameter and handle the default internally, if you don't need to use null as a legit value
You could do something like this:
getUser()?.let { // user is not null
doSomething(it)
} ?: run { // user is null here
doSomething()
}
(cf: Swift 'if let' statement equivalent in Kotlin)
I don't think you could do something shorter without making the code hard to understand Edit 2: Actually you can, see the comment
Edit: I would personally handle the nullable variable inside the function like this:
fun doSomething(user: User?) {
val correctUser = user ?: defaultUser
//do something
}
so you can use the function like this:
doSomething(getUser())
I agree with cactustictacs, just putting it on one line is clear and simple. However, if you use it often and it's bothering you, it's easy enough to wrap it in a function without the default parameter:
fun doSomethingSensibly(user: User?) =
if (user == null)
doSomething()
else
doSomething(user)
Which can be used as:
doSomethingSensibly(getUser())

Kotlin: lambda run alternative scenario

I have userDto, contains programs, which contains actual field. Actual program can be only one. I need to get it. Than, I run this:
userDto.programs.sortedBy { it.created }.findLast { it.actual }?
Okay, but I want to foresee case, when findLast returns null, & throw exception. Please, advice, how to do it?
UPD:
ProgramType.valueOf(userDto.programs
.sortedBy { it.created }
.findLast { it.actual }
//check here
!!.programType!!).percentage
You are pretty close actually :)! What you could do is:
userDto.programs.sortedBy { it.created }.findLast { it.actual } ?: throw RuntimeException()
Or if you're trying to actually avoid throwing an error(couldn't really tell with the way question is asked), you could just do an error check like this:
userDto.programs.sortedBy { it.created }.findLast { it.actual }?.let{
//rest of your code goes here
}
Hope this helps, cheers!

Is the return statement and the end if the method required if the method return value is void?

If I have for example this piece of code:
- (void)doSomething
{
// do whatever the method has to do
return;
}
I know that the return is not required for the app to keep running. It seems to be smart enough to know that the method has finished. My question is: Does the absence of the return have negative side effects? (e.g. a memory leak)
Of course not, return has no meaning in void methods except if you wanna return early based on condition or failure to stop execution rest of method.

How to enforce parameters of anonymous blocks to be unused in Objective-C?

I've run into a situation while using a library called TransitionKit (helps you write state machines) where I am want to supply entry and exit actions in the form of a callback.
Sadly, the callbacks include two completely useless parameters. A typical block has to look like this:
^void (TKState *state, TKStateMachine *stateMachine) {
// I TOTALLY don't want parameters `state` or `stateMachine` used here
};
(this is an anonymous code block. Read up on blocks here if you're unclear)
As I've noted in the comment, I really don't want those parameters even mentioned in the body there. I've tried simply removing the parameter names like suggested in this question like so:
^void (TKState *, TKStateMachine *) {
// I foobar all I like here
};
but sadly the code won't compile then :(.
How can I enforce this non-usage of parameters in code?
This is what I could come up with. Quite a hack and relies on the GCC poison pragma, which is not standard but a GNU extension - although, given that you are probably compiling this with clang anyway, it should not be a problem.
#define _state state
#define _stateMachine stateMachine
#pragma GCC poison state stateMachine
Then this compiles:
^(TKState *_state, TKStateMachine *_stateMachine) {
do_something();
}
But this doesn't:
^(TKState *_state, TKStateMachine *_stateMachine) {
do_something(state, stateMachine);
}
You could just have a function that took one kind of block, and returned another, like this:
#class TKState, TKStateMachine; // here so this will compile
typedef void (^LongStateBlock)(TKState *state, TKStateMachine *stateMachine);
static inline LongStateBlock Adapter(void(^block)()) {
void(^heapBlock)() = [block copy]; // forces block to be on heap rather than stack, a one-time expense
LongStateBlock longBlock = ^(TKState *s __unused, TKStateMachine *sm __unused) {
heapBlock();
};
// this is the non-ARC, MRR version; I'll leave ARC for the interested observer
[heapBlock release];
return [[longBlock copy] autorelease];
}
And in practice:
// this represents a library method
- (void)takesLongStateBlock:(LongStateBlock)longBlock
{
// which hopefully wouldn't look exactly like this
if (longBlock) longBlock(nil, nil);
}
- (void)yourRandomMethod
{
[self takesLongStateBlock:^(TKState *state, TKStateMachine *stateMachine) {
NSLog(#"Gratuitous parameters, AAAAHHHH!");
}];
[self takesLongStateBlock:Adapter(^{
NSLog(#"So, so clean.");
})];
}
The whole thing is gisted, and should compile inside any class. It does what you expect when you call -yourRandomMethod.
AFAIK there is no way to do what you want when you are creating a block, you can only miss the parameter names when you are declaring a block variable(a reference to a block, to avoid misunderstandings)
So here you can miss the param names:
void (^myBlock)(SomeClass *);
But not when you create a block:
myBlock = ^(SomeClass *o)
{
};
I'd write
^void (TKState *unused_state, TKStateMachine *unused_stateMachine) {
// Anyone using unused_state or unused_stateMachine gets what they deserve.
};
Of course someone can use the parameters. But then whatever you do, they can change the code. If someone is intent on shooting themselves in the foot, there is no stopping them.