The scenario is as follows. The API of my program will allow the user to perform some method on a particular element (let's say a tuple from a database). If this parameter is not passed to the function, then the "default" behavior is to look for a list of elements (from a database query, for example) and to act on all of them. Like this:
task(simple_object) # will process simple_object task() # query the database with some previously defined query
And this is what I did (implementation in Python):
@task(query='SELECT * FROM User WHERE age < 18') def task_disable_account(user): disable_user(user)
This way I can call the
task_disable_account with one particular
User or I can call it with no arguments and then every tuple from the SQL query will be processed. The definition of
task decorator is as follows:
task_registry =  def task(query): Task = namedtuple('Task', ['func', 'query']) def decorate(func): def queried(*_args): if not _args: map(func, search(query)) # execute on result from SQL return return func(*_args) # execute on 1 passed parameter task_registry.append(Task(queried, query)) return queried return decorate
And this is how I use it (just an example, actual code is more complicated):
def main(): # lets assume a main() function for func, _ in task_registry: # I'm getting and ID from sys.argv and returning a User object # If not passed via arguments, call function with no parameters user = get_from_argv() if user: func(user) else: func()
The idea behind all this is:
tasked method should only take care of the processing of 1 element, centralising the way we search for, and how we iterate over them.
- Make it easy to add new
taskmethods to our implementation, not having to repeat the boilerplate code over and over.