Where to run parameter validation - structure

Lets say we have a function, and a caller to that function
function baz(){
myVar = null;
foo(myVar);
}
function foo(bar){
//do stuff
}
where should validation on the parameters happen?
It could be
function baz(){
myVar = null;
if(myVar != null){
foo(myVar);
}
}
or it could be
function foo(bar){
if(myVar == null) return null;
//do stuff
}
What is better? Or if it's situational, when should I use what?
Perhaps an extension of this would also be when should I do
myVar['key'] = myFunc();
function myFunc(){
return x;
}
vs
myFunc();
function myFunc(myVar){
myVar['key'] = x;
}

It very much depends. If you are implementing for speed, you may want to consider leavin the choice of validation to the user. If you are implementing for stability, you may want to validate as part of the function.
Imagine an array and the push() function validates. Now imagine using that function a a few hundred times per frame at 60 FPS in a game. That's an extra >6000 if calls per second. Thats a big enough number to matter.

Related

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())

Clean code - what should I do to avoid passing two arguments

I recently read "clean code" from Robert C.Martin and some concepts are unclear for me.
I have this object
export class SyncErrorList{
constructor(
public SignatureErrors: SignatureSyncError[],
public ArErrors: ARSyncError[],
public EnrSyncError: EnrSyncError[]
){}
}
I want to make a function that delete a "syncerror" from a list. I want to pass this functions the type of list and the index, is it a bad design because the function wil take two arguments ?
deleteErrorByErrorAndIndex(SyncError: DocSyncError, index: number){
if(SyncError instanceof SignatureSyncError){
this.SignatureErrors.splice(index, 1);
}
if(SyncError instanceof ARSyncError){
this.ArErrors.splice(index, 1);
}
if(SyncError instanceof EnrSyncError){
this.EnrSyncError.splice(index, 1);
}
}
It's hard for me to determine when a function that takes two parameters is "acceptable". I technically could just pass the syncerror and search for it in the list to get the index, but it would be less optimized, is my case one of the cases it would be acceptable ? If not, what should I do ?
you could decouple and create separate methods for example:
deleteSignatureErrorsByIndex(index: number){
this.SignatureErrors.splice(index, 1);
}
deleteSignatureErrorsByIndex(index: number){
this.ArErrors.splice(index, 1);
}
deleteEnrSyncErrorByIndex(index: number){
this.EnrSyncError.splice(index, 1);
}
that being said, it's just a suggestion. having two function params is fine, it's the if else part that is dirty.

Writing Custom Rule for Android-Lint

Q (tldr;): How do I use the JavaScanner in android-lint to check if a particular function call with a specific string as a parameter has been surrounded by a try/catch block.
Details: I have completed the android-lint tutorials on the official site and have gone through the source of the existing lint-checks. However, I can't seem to grasp the workflow for this AST-based parsing of JavaScanner. What I'm trying to achieve is to catch a function that sets a specific property and surround it with a try/catch block. For example:
MyPropertySettings.set("SOME_PROPERTY", "SOME_VAL");
should not trigger the lint rule but:
MyPropertySettings.set("SOME_SENSITIVE_PROPERTY", "SOME_VAL");
should because it's not surrounded by a try/catch block with SetPropertyException. I don't want to introduce the try/catch to the function itself because it only throws the exception in extremely rare cases (and the internals of the function are based on some reflection mojo).
For this question, even a workflow/hint would be fine. If I can get the first few steps, I might be able to grasp it better.
Update:
After some more study, I have found that I need to set the set function above in getApplicableMethodNames() and then, somehow read the property of that function to decide if the check applies. That part should be easy.
Surrounding try/catch would be more difficult and I gather I would need to do some "flow analysis". How is the question now.
Well, along with the getApplicableMethodNames() method, you need to override the visitMethod() function. You will get the MethodInvocationNode. Just fetch the arguments passed in the invocation using the node.astArguments() function. This returns a list of arguments that you can iterate through using a StrictListAccessor. Check the arguments passed and if it matches your criterion, run a loop and keep calculating the parent node of the invocation node till a try node is found. If it is a try node, then you can get a list of catches using node.astCatches(). Scan the list and find the appropriate exception. If not found, then report.
You can code like this:
check if it is surrounded by try/catch:
#Override
public void visitMethod(JavaContext context, AstVisitor visitor, MethodInvocation node) {
// check the specified class that invoke the method
JavaParser.ResolvedMethod method = (JavaParser.ResolvedMethod) context.resolve(node);
JavaParser.ResolvedClass clzz = method.getContainingClass();
boolean isSubClass = false;
// sSupportSuperType = {"class name"};
for (int i = 0; i < sSupportSuperType.length; i++) {
if (clzz.isSubclassOf(sSupportSuperType[i], false)) {
isSubClass = true;
break;
}
}
if (!isSubClass) return;
// check if surrounded by try/catch
Node parent = node;
while (true) {
Try tryCatch = context.getParentOfType(parent, Try.class);
if (tryCatch == null) {
break;
} else {
for (Catch aCatch : tryCatch.astCatches()) {
TypeReference catchType = aCatch.astExceptionDeclaration().astTypeReference();
}
parent = tryCatch;
}
}
// get the arguments string
String str = node.astArguments().first().toString();
if (!str.startsWith("\"SOME_PROPERTY\"")) {
context.report(ISSUE, node, context.getLocation(node), "message");
}
}
before this you have to define the specific method by override:
#Override
public List<String> getApplicableMethodNames() {
return Collections.singletonList("set");
}

Getting the code of released key

I'm trying to make a simple platformer using action script 2.0 but I have a problem with getting input from keyboard. I have two function "myKeyDown" and "myKeyUp" that get called whenever a key is pressed down/released.
keyListener.onKeyDown = function(){
myKeyDown();
}
keyListener.onKeyUp = function(){
myKeyUp();
}
The functions check which key was pressed by using Key.getCode() method. It works for myKeyDown but it's buggy for myKeyUp. The bug happens if (for example) I first press A (to move left), then W (to jump), then release W and then release A. The player won't stop moving (even though that's what should happen when you release A)
I understand the problem here. Key.getcode return the code of the last pressed key and what I want is the code for the last released key. I've been searching for hours for a function like this but I haven't found anything.
Here's the code for both myKeyDown and myKeyUp functions
function myKeyDown(){
//A
if(Key.getCode() == 65){
velX=-3;
}else
//D
if(Key.getCode() == 68){
velX=3;
}else
//W
if(Key.getCode() == 87){
if(isInAir == false){
jump();
}
}
}
function myKeyUp(){
//A
if(Key.getCode() == 65){
if(velX==-3){
velX=0;
}
}else
//D
if(Key.getCode() == 68){
if(velX==3){
velX=0;
}
}
}
for cases like this, when you need to hold/release multiple keys a little bit different approach would be better for key handling.
what you can do is use onEnterFrame event listener to check for the pressed keys in case of events when something has to be continuous.
an example
var my_keys:Array = new Array();
my_keys["jump"]=false;
my_keys["right"]=false;
my_keys["left"]=false;
//keydown sets the variables to true
keyListener.onKeyDown = function(){
code=Key.getCode();
if(code==65){
my_keys["left"]=true;
}
if(code==68){
my_keys["right"]=true;
}
if(code==87){
my_keys["jump"]=true;
}
//etc, etc, anything else you wish
//of course, this doesn't prevent you from calling additional one-time events from the keydown!
}
//keyup unsets the button variables
keyListener.onKeyUp = function(){
code=Key.getCode();
if(code==65){
my_keys["left"]=false;
}
if(code==68){
my_keys["right"]=false;
}
if(code==87){
my_keys["jump"]=false;
}
}
now at every point of your game you have a set of keys that are pressed stored in the my_keys array. of course you could use a more generic function inside the keyDown/keyUp and pass the Key.getCode itself directly into the array as indexes instead of the captioned array (like my_keys[Key.getCode()]=true;), it would be even shorter to write. however, i found this to be more illustrative as an example, feel free to modify the code as you need
what you want now is a function that would handle the behavior based on what keys are pressed.
in your case this could, for example, be:
this.onEnterFrame=function(){ //you don't have to use "this" movieclip reference if you have other enterframe events in the movieclip. just don't forget to modify the objcet paths
if(my_keys["left"]){
velX=-3;
}
if(my_keys["right"]){
velX=+3;
}
if((my_keys["jump"])&&(!isInAir)){ //note that i added !isInAir instead of (isInAir==false). this is an equivalent expression, it's just shorter and nicer
jump();
}
}

optimal way of passing multiple callback functions as arguments?

I have a function that could be used in CLI or web application, that being said, there is a little difference in the process; for example: if I'm using this function for CLI it'll use a text progress bar, but that doesn't make sense if I'm using this function for a web application.
The function is basically a loop; so what i'm looking for is a way to make this function flexible by making it possible to pass code as an argument so that it'll be executed at the end of each loop cycle. So if I'm using this function in CLI; i'll pass a progress incremental function to advance the progress bar, and so on.
My current solution is to pass a progress bar object instance, which I think isn't a proper solution; because it doesn't seem flexible for the long run.
A demonstration example of what I'm already doing:
function myFunction($progressBar = null)
{
for($i = 0; $i......)
{
//Do stuff
....
//finally...
if(!empty($progressBar))
$progressBar->advance();
}
}
So, if I want to add another function at the end of the loop, I'll have to pass it as an argument and call it manually later; but as I said, it just doesn't seem right.
I'm thinking of using a callback function(an anonymous function being passed to myFunction) But what is a proper way of doing that; should I just make each callback function as an individual argument? or, to make it even more flexible, should I be grouping all callback functions in an array(if that's possible).
Yes, you can use callbacks for this.
function myFunction($progressBar = null, callable $callback = null)
{
for($i = 0; $i......)
{
//Do stuff
....
//finally...
if(!empty($progressBar))
$progressBar->advance();
}
if ($callback){ //Execute the callback if it is passed as a parameter
$callback();
}
}
Also, you can specify parameters for an anonymous function:
Example: you want to echo something at some point.
myFunction($progressBar) ; //No need yet
myFunction($progressBar, function($result){ echo $result ; }) ; //Now you want to execute it
So, handle it in an appropriate way:
if ($callback){ //Execute the callback if it is passed as a parameter
$callback("All is fine"); //Execute the callback and pass a parameter
}
Array of callbacks also may be useful in this case like:
$callbacks = array(
"onStart" => function(){ echo "started" ; },
"onEnd" => function(){ echo "ended" ; }
) ;
function myFunc($progressBar = null, $callbacks){
if (isset($callbacks["onStart"]) && is_callable($callbacks["onStart"])){
$callbacks["onStart"]() ;//Execute on start.
}
//Execute your code
if (isset($callbacks["onEnd"]) && is_callable($callbacks["onEnd"])){
$callbacks["onEnd"]() ;//Execute on end.
}
}