Reputation: 54242
I have a function with a bunch of arguments, and I just want to check if any of them are falsy (empty, undefined, null, etc.).
One option is obvious to just check every argument individually, but it's pretty repetitive:
if not arg1
response.send 400, 'Missing argument arg1'
if not arg2
response.send 400, 'Missing argument arg2'
I can simplify that a bit with this, but I still have to list out every every argument and argument name:
for key, value of { 'arg1': arg1, 'arg2': arg2 }
if not value
response.send 400, "Missing argument #{key}"
I was hoping to do something like this:
for key, value of arguments
if not value
response.send 400, "Missing argument #{key}"
But arguments
is more like an array. Is there a way to get the arguments as an object, or get the argument names as an array? Am I going about this this wrong way?
What is a good way of validating a bunch of arguments without repeating myself?
Upvotes: 0
Views: 341
Reputation: 3305
I believe there is no clear way of achieving what you want, but a nasty way of doing this (based on similar threads for javascript, like this and this), which may be error prone, is to parse the function itself, get the names of the arguments and make them an array:
fn = (a,b,c,d,e,f) ->
fns = fn.toString()
args = fns.slice(fns.indexOf('(')+1, fns.indexOf(')')).split(', ')
for idx in [0...args.length]
console.log 400, "Missing argument #{args[idx]}" unless arguments[idx]
fn('', null, 'arg1', undefined, 'arg2')
#Output:
#400 'Missing argument a'
#400 'Missing argument b'
#400 'Missing argument d'
#400 'Missing argument f'
Upvotes: 1
Reputation: 9934
You could write an check function that parses the parameter names from the string representation of your function (there is really no other way)
check = ()->
f = "" + arguments.callee.caller
r = /function \((.*)\)/
regres = r.exec(f)
pnames = regres[1].split(",")
params = (pn.trim() for pn in pnames)
for index in [0...arguments.length]
if arguments[index] == null || arguments[index] == undefined
console.log "argument: #{params[index]} is null"
handleRequest = (x, y, z)->
#give all your params in the correct order to the check function
check(x, y, z)
handleRequest(1, 2, "lala")
handleRequest(1, 2)
Now the fact that this is somehow possible shouldn't mean that you should do it. This solution is at best brittle and will create confusion if you change parameter position. Some would probably claim its evil - me included ;-)
I'd rather advise you that you change your API design.
From your response.send I would assume that you are in an web environment? Why dont you simply use the params hash that the framework you are using is handling to you? Most frameworks will do exactly this.
Another possibility would be to define default values for your parameter so that received parameters are always well defined?
handleRequest = (x, y = "somevalue", z = "anothervalue")->
Upvotes: 2