{"id":13520093,"url":"https://github.com/torch/argcheck","last_synced_at":"2025-10-09T21:40:02.966Z","repository":{"id":7053282,"uuid":"8334127","full_name":"torch/argcheck","owner":"torch","description":"A powerful (and blazing fast) argument checker and function overloading system for Lua or LuaJIT","archived":false,"fork":false,"pushed_at":"2016-06-29T21:37:54.000Z","size":710,"stargazers_count":54,"open_issues_count":9,"forks_count":17,"subscribers_count":11,"default_branch":"master","last_synced_at":"2024-11-02T02:34:11.962Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Lua","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/torch.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-02-21T11:47:50.000Z","updated_at":"2024-10-10T09:13:33.000Z","dependencies_parsed_at":"2022-09-22T11:31:21.761Z","dependency_job_id":null,"html_url":"https://github.com/torch/argcheck","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/torch/argcheck","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/torch%2Fargcheck","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/torch%2Fargcheck/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/torch%2Fargcheck/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/torch%2Fargcheck/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/torch","download_url":"https://codeload.github.com/torch/argcheck/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/torch%2Fargcheck/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279002054,"owners_count":26083286,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-09T02:00:07.460Z","response_time":59,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T05:02:11.168Z","updated_at":"2025-10-09T21:40:02.946Z","avatar_url":"https://github.com/torch.png","language":"Lua","readme":"argcheck\n========\n\nA powerful function argument checker and function overloading system for\nLua or LuaJIT.\n\n`argcheck` generates specific code for checking arguments of a function. This\nallows complex argument checking (possibly with optional values), with\nlittle overhead (with [LuaJIT](http://luajit.org)). `argcheck` computes a\ntree of all possible variants of arguments, allowing efficient overloading\nand default argument management.\n\nInstallation\n------------\n\nThe easiest is to use [luarocks](http://www.luarocks.org).\n\nIf you use Torch, simply do\n```sh\nluarocks install argcheck\n```\nelse\n```sh\nluarocks build https://raw.github.com/torch/argcheck/master/rocks/argcheck-scm-1.rockspec\n```\n\nYou can also copy the `argcheck` directory where `luajit` (or `lua`) will\nfind it.\n\nChangelog\n---------\n\n  - Version 2.0 (git)\n     - Rewrote completely the code generation.\n     - Now creates a tree of possible argument paths (much more efficient).\n     - Thanks to the tree approach, many bugs have been fixed.\n     - `argcheck` will produce an error if there are ambiguous argument rules.\n     - The feature `chain` is still deprecated (but available). Use `overload` instead.\n     - True overloading is happening. Contrary to `chain`, `overload` functions must be overwritten.\n     - Same functionalities than in 1.0, plus\n        - Handles named method calls\n        - Can generate a dot graphviz file of the argument paths for debugging purposes.\n\n  - Version 1.0\n     - Simplified the way of calling `argcheck`.\n     - Same functionalities than before, except named method call were not handled anymore.\n     - Added the `call` option to call a function if the arguments match given rules.\n     - Added the `chain` option to chain several `argcheck` function calls (a cheap version of overloading).\n     - Simplified the way of adding a type.\n\n  - Version 0.5\n     - Handling of default arguments (including defaulting to another argument), optional arguments (which might be `nil`), named arguments, named only option.\n     - Complicated way to handle method and functions.\n     - Calling function is mandatory.\n\n\nDocumentation\n------------\n\nTo use `argcheck`, you have to first `require` it:\n```lua\nlocal argcheck = require 'argcheck'\n```\nIn the following, we assume this has been done in your script.\nNote that `argcheck` does not import anything globally, to avoid cluttering\nthe global namespace.  The value returned by the require is a function: for\nmost usages, it will be the only thing you need.\n\n_Note that in the following examples we do not use local variables for\ncheck functions or example functions. This is bad practice, but helpful if\nyou want to cut-and-paste the code in your interactive lua to see how\nthis is running._\n\nThe `argcheck()` function creates a fast pre-compiled function for checking\narguments, according to rules provided by the user. Assume you have a\nfunction which requires a unique number argument:\n```lua\nfunction addfive(x)\n  print(string.format('%f + 5 = %f', x, x + 5))\nend\n```\nYou can make sure everything goes fine by creating the rule:\n```lua\ncheck = argcheck{\n   {name=\"x\", type=\"number\"}\n}\n\nfunction addfive(...)\n   local x = check(...)\n   print(string.format('%f + 5 = %f', x, x + 5))\nend\n```\nIf a user try to pass a wrong argument, too many arguments, or no arguments\nat all, `argcheck` will complain:\n```lua\narguments:\n{\n  x = number  --\n}\n\nstdin:2: invalid arguments\n```\n\nA rule must at least take a `name` field. The `type` field is optional\n(even though it is highly recommended!). If `type` is not provided, `argcheck` will make\nsure the given argument is not `nil`. If you want also to accept `nil` arguments, see the\n[`opt` option](#argcheck.opt).\n\n### Default arguments\nArguments can have defaults:\n```lua\ncheck = argcheck{\n   {name=\"x\", type=\"number\", default=0}\n}\n```\nIn which case, if the argument is missing, `argcheck` will pass the default\none to your function:\n```lua\n\u003e addfive()\n0.000000 + 5 = 5.000000\n```\n\n### Help (or doc)\n`argcheck` encourages you to add help to your function. You can document each argument:\n```lua\ncheck = argcheck{\n   {name=\"x\", type=\"number\", default=0, help=\"the age of the captain\"}\n}\n```\nOr even document the function:\n```lua\ncheck = argcheck{\n   help=[[\nThis function is going to do a simple addition.\nGive a number, it adds 5. Amazing.\n]],\n   {name=\"x\", type=\"number\", default=0, help=\"the age of the captain\"}\n}\n```\nThen, if the user makes a mistake in the arguments, the error message\nbecomes more clear:\n```lua\n\u003e addfive('')\nstdin:2: invalid arguments\n\nThis function is going to do a simple addition.\nGive a number, it adds 5. Amazing.\n\narguments:\n{\n   [x = number]  -- the age of the captain [default=0]\n}\n```\n\nNote that is (equivalently) possible to use the key `doc=` instead of `help=`.\n\n### Multiple arguments\n\nUntil now, our function had only one argument. Obviously, `argcheck` can\nhandle as many as you wish:\n```lua\ncheck = argcheck{\n   help=[[\nThis function is going to do a simple addition.\nGive a number, it adds 5. Amazing.\n]],\n   {name=\"x\", type=\"number\", default=0, help=\"the age of the captain\"},\n   {name=\"msg\", type=\"string\", help=\"a message\"}\n}\n\nfunction addfive(...)\n  local x, msg = check(...)\n  print(string.format('%f + 5 = %f', x, x + 5))\n  print(msg)\nend\n```\n`argcheck` handles well various cases, including those where some arguments\nwith defaults values might be missing:\n```lua\n\u003e addfive(4, 'hello world')\n4.000000 + 5 = 9.000000\nhello world\n\u003e\n\u003e addfive('hello world')\n0.000000 + 5 = 5.000000\nhello world\n\u003e\n\u003e addfive(4)\n\nstdin:2: invalid arguments\n\nThis function is going to do a simple addition.\nGive a number, it adds 5. Amazing.\n\narguments:\n{\n  [x   = number]  -- the age of the captain [default=0]\n   msg = string   -- a message\n}\n```\n\n### Default argument defaulting to another argument\n\nArguments can have a default value coming from another argument, with the\n`defaulta` option. In the following\n```lua\n\ncheck = argcheck{\n  {name=\"x\", type=\"number\"},\n  {name=\"y\", type=\"number\", defaulta=\"x\"}\n}\n\nfunction mul(...)\n   local x, y = check(...)\n   print(string.format('%f x %f = %f', x, y, x * y))\nend\n```\nargument `y` will take the value of `x` if it is not passed during the function call:\n```lua\n\u003e mul(3, 4)\n3.000000 x 4.000000 = 12.000000\n\u003e mul(3)\n3.000000 x 3.000000 = 9.000000\n```\n\n### Default arguments function\n\nIn some more complex cases, sometimes one needs to run a particular function when\nthe given argument is not provided. The option `defaultf` is here to help.\n```lua\n\nidx = 0\n\ncheck = argcheck{\n   {name=\"x\", type=\"number\"},\n   {name=\"y\", type=\"number\", defaultf=function() idx = idx + 1 return idx end}\n}\n\nfunction mul(...)\n   local x, y = check(...)\n   print(string.format('%f x %f = %f', x, y, x * y))\nend\n```\n\nThis will output the following:\n```lua\n\u003e mul(3)\n3.000000 x 1.000000 = 3.000000\n\u003e mul(3)\n3.000000 x 2.000000 = 6.000000\n\u003e mul(3)\n3.000000 x 3.000000 = 9.000000\n```\n\n\u003ca name=\"argcheck.opt\"/\u003e\n### Optional arguments\n\nArguments with a default value can be seen as optional. However, as they\ndo have a default value, the underlying function will never receive a `nil`\nvalue. In some situations, one might need to declare an optional argument\nwith no default value. You can do this with the `opt` option.\n```lua\ncheck = argcheck{\n  {name=\"x\", type=\"number\", default=0, help=\"the age of the captain\"},\n  {name=\"msg\", type=\"string\", help=\"a message\", opt=true}\n}\n\nfunction addfive(...)\n   local x, msg = check(...)\n   print(string.format('%f + 5 = %f', x, x + 5))\n   print(msg)\nend\n```\nIn this example, one might call `addfive()` without the `msg` argument. Of\ncourse, the underlying function must be able to handle `nil` values:\n```lua\n\u003e addfive('hello world')\n0.000000 + 5 = 5.000000\nhello world\n\u003e addfive()\n0.000000 + 5 = 5.000000\nnil\n```\n\n### Torch Tensors\n`argcheck` supports Torch `Tensors` type checks.\nSpecific tensor types like `Int`, `Float`, or `Double` can be\nchecked with `torch.\u003cType\u003eTensor`.\nAny tensor type can be checked with `torch.*Tensor`.\n\n```lua\ncheck = argcheck{\n  {name=\"anyTensor\", type=\"torch.*Tensor\"},\n  {name=\"fTensor\", type=\"torch.FloatTensor\"}\n}\n\ncheck(torch.IntTensor(), torch.FloatTensor()) -- Good.\ncheck(torch.FloatTensor(), torch.FloatTensor()) -- Good.\ncheck(torch.FloatTensor(), torch.IntTensor()) -- Invalid.\n```\n\n\n### Specific per-rule check\n\nIt is possible to add an extra specific checking function for a given checking\nrule, with the `check` option. This function will be called (with the corresponding argument)\nin addition to the standard type checking. This can be useful for refined argument selection:\n```lua\ncheck = argcheck{\n  {name=\"x\", type=\"number\", help=\"a number between one and ten\",\n    check=function(x)\n            return x \u003e= 1 and x \u003c= 10\n          end}\n}\n\nfunction addfive(...)\n   local x = check(...)\n   print(string.format('%f + 5 = %f', x, x + 5))\nend\n\n\u003e addfive(3)\n3.000000 + 5 = 8.000000\n\n\u003e addfive(11)\nstdin:2: invalid arguments\n\narguments:\n{\n   x = number  -- a number between one and ten\n}\n```\n\n### Named arguments\n\n`argcheck` handles named argument calls. Following the previous example, both\n```lua\naddfive(1, \"hello world\")\n```\nand\n```lua\naddfive{x=1, msg=\"hello world\"}\n```\nare valid. However, ordered arguments are handled in a *much faster* way\n(especially with LuaJIT) than named arguments.\n\n### Method named arguments\n\nThe common way to define a \"method\" in Lua is by doing the following:\n```lua\nlocal object = {}\n\nfunction object:foobar(x, msg) -- a method foobar\nend\n```\n\nThe syntax sugar call `object:foobar(x, msg)` is equivalent to the function call\n```lua\nobject.foobar(object, x, msg)\n```\n\nCalling a method with named arguments would be done with\n```lua\nobject:foobar{x=..., msg=...}\n```\n(where `...` is the actual content of x and msg). This translates to\n`foobar(object, {x=..., msg=...})`, which is not a regular named function\ncall, given that the `object` itself should not be treated as a named\nargument. `argcheck` will handle such calls, provided the name of the object\nargument is `self`, in the rule definition. For e.g.:\n```lua\nlocal object = {checksum=1234567} -- the object is just a table here\nlocal check = argcheck{\n   {name=\"self\", type=\"table\"}, -- check the type of self\n   {name=\"x\", type=\"number\"},\n   {name=\"msg\", type=\"string\", default=\"i know what i am doing\"},\n}\n\nfunction object.foobar(...) -- note the '.', given we type-check self too\n   local self, x, msg = check(...)\n   print(string.format('%f + 5 = %f [msg = %s] [self.checksum=%s]', x, x + 5, msg, self.checksum))\nend\n\n-- method ordered arguments call\n\u003e object:foobar(5, 'hello world')\n5.000000 + 5 = 10.000000 [msg = hello world] [self.checksum=1234567]\n\n-- method named arguments call (works too!)\n\u003e object:foobar{x=5, msg='hello world'}\n5.000000 + 5 = 10.000000 [msg = hello world] [self.checksum=1234567]\n\n-- default argument (and other things) work the same than previously\n\u003e object:foobar(7)\n7.000000 + 5 = 12.000000 [msg = i know what i am doing] [self.checksum=1234567]\n\n\u003e object:foobar{x=7}\n7.000000 + 5 = 12.000000 [msg = i know what i am doing] [self.checksum=1234567]\n```\n\nNote: `argcheck` assumes the function defined by a set of rules is in fact\na method, if the name of the first rule is `self`.\n\n### Options global to all rules\n\n`argcheck` has several interesting global options, as the `help` (or `doc`) we have introduced already.\nThose global options are simply set in the main `argcheck` table:\n```lua\ncheck = argcheck{\n   help = \"blah blah\", -- global help option\n...\n}\n```\nOther global options are described in the following.\n\n#### Function call\n\nAn important feature of `argcheck` is its ability to call a function if the\npassed arguments match the defined rules.\n\nTaking back the first example, one could use the `call` option and rewrite\nit as:\n```lua\naddfive = argcheck{\n   {name=\"x\", type=\"number\"},\n\n   call = function(x)\n            print(string.format('%f + 5 = %f', x, x + 5))\n          end\n}\n\n\u003e addfive(5)\n5.000000 + 5 = 10.000000\n\n\u003e addfive()\nstdin:1: arguments:\n{\n   x = number  --\n}\n```\n\nAs we will see below, `argcheck` can also handle function overloading, and\nother complex situations, in which the `call` feature can simplify the\nprogrammer's life. In that respect, it is highly encouraged to use this\nfeature.\n\n#### Pack arguments into a table\n\nIn some cases, it might be interesting to get all arguments into a\ntable. This is not recommended in general, as creating a table slows down\nthe checking process. However, when one uses *a lot* of arguments, the\n`pack` option might be of interest. The function created by `argcheck`\nthen returns a table containing all arguments with rule names as keys.\n```lua\ncheck = argcheck{\n   pack=true,\n   {name=\"x\", type=\"number\", default=0, help=\"the age of the captain\"},\n   {name=\"msg\", type=\"string\", help=\"a message\"}\n}\n\nfunction addfive(...)\n   local args = check(...) -- now arguments are stored in this table\n   print(string.format('%f + 5 = %f', args.x, args.x+5))\n   print(args.msg)\nend\n\n\u003e addfive(5, 'hello world')\n5.000000 + 5 = 10.000000\nhello world\n```\n\n#### Restrict to named-only or ordered-only arguments\n\nIn some very special (rare) cases, one might want to disable named calls\nlike `addfive{x=1, msg='blah'}`, and stick to only ordered arguments like\n`addfive(1, 'blah')`, or vice-versa. That might be to handle some ambiguous\ncalls, e.g. when one has to deal with table arguments. The options\n`nonamed` and `noordered` can be used for that purpose:\n\n```lua\ncheck = argcheck{\n   nonamed=true,\n   {name=\"x\", type=\"number\", default=0, help=\"the age of the captain\"},\n   {name=\"msg\", type=\"string\", help=\"a message\"}\n}\n\nfunction addfive(...)\n   local x, msg = check(...)\n   print(string.format('%f + 5 = %f', x, x+5))\n   print(msg)\nend\n\n\u003e addfive('blah')\n0.000000 + 5 = 5.000000\nblah\n\n\u003e addfive{msg='blah'}\nstdin:2: invalid arguments\n\narguments:\n{\n   [x   = number]  -- the age of the captain [default=0]\n   msg = string   -- a message\n}\n```\n\n#### Quiet\n\nIf you want to handle errors yourself, you might want to make sure the\nchecking function is quiet. The `quiet=true` option is here for this. If\nmentioned, the argument checker will return a boolean (`true` in case of\nsuccess, `false` if arguments do not match rules), followed by the\narguments (possibly packed). In case of failure `false` is followed by the\nhelp message.\n\n```lua\ncheck = argcheck{\n   quiet=true,\n   {name=\"x\", type=\"number\", default=0, help=\"the age of the captain\"},\n   {name=\"msg\", type=\"string\", help=\"a message\"}\n}\n\n\u003e print(check(5, 'hello world'))\ntrue             5      hello world\n\n\u003e print(check(5))\nfalse   arguments:\n{\n  [x   = number]  -- the age of the captain [default=0]\n   msg = string   -- a message\n}\n```\n\n#### Overloading\n\nIt is possible to overload previous created `argcheck`s manually. E.g., in our example,\nif we want `addfive()` to handle the case of a number or string argument,\none could leverage the `quiet` global option and do the following:\n```lua\nchecknum = argcheck{\n   quiet=true,\n   {name=\"x\", type=\"number\"}\n}\n\ncheckstr = argcheck{\n   quiet=true,\n   {name=\"str\", type=\"string\"}\n}\n\nfunction addfive(...)\n\n  -- first case\n  local status, x = checknum(...)\n  if status then\n    print(string.format('%f + 5 = %f', x, x + 5))\n    return\n  end\n\n  -- second case\n  local status, str = checkstr(...)\n  if status then\n    print(string.format('%s .. 5 = %s', str, str .. '5'))\n    return\n  end\n\n  -- note that in case of failure with quiet, the error is returned after the status\n  print('usage:\\n\\n' .. x .. '\\n\\nor\\n\\n' .. str)\n  error('invalid arguments')\nend\n\n\u003e addfive(123)\n123.000000 + 5 = 128.000000\n\n\u003e addfive('hi')\nhi .. 5 = hi5\n\n\u003e addfive()\nusage:\n\narguments:\n{\n   x = number  --\n}\n\nor\n\narguments:\n{\n   str = string  --\n}\nstdin:19: invalid arguments\n```\n\nThis can however quickly become a burden, if there are many possible\nargument variations. Instead, one can use the `overload` option, which is\nsupposed to be used together with `call`. The value provided to `overload`\nmust be a function previously created by `argcheck`.\n\nIf the arguments do not match any given variations, then the created\nargument checker will show a global error message, with usage summarizing\nall possibilites.\n\nWhen overloading, `argcheck` will create a new function (for efficiency\nreasons) including all possible cases which are being overloaded, as well\nas the new given case. _Beware_ to overwrite the returned `argcheck`\nfunction each time you overload one!\n\nThe previous example is then equivalent to:\n```lua\naddfive = argcheck{\n  {name=\"x\", type=\"number\"},\n  call = function(x) -- called in case of success\n           print(string.format('%f + 5 = %f', x, x + 5))\n         end\n}\n\naddfive = argcheck{ -- overwrite it\n  {name=\"str\", type=\"string\"},\n  overload = addfive, -- overload the previous one\n  call = function(str) -- called in case of success\n           print(string.format('%s .. 5 = %s', str, str .. '5'))\n         end\n}\n\nth\u003e addfive(5)\n5.000000 + 5 = 10.000000\n\nth\u003e addfive('hi')\nhi .. 5 = hi5\n\nth\u003e addfive()\nstdin:1: arguments:\n{\n   x = number  --\n}\n\nor\n\narguments:\n{\n   str = string  --\n}\n```\n\n#### Force\n\n`argcheck` hates ambiguities, and will spit out an error message if you try\nto create some rules which are ambiguous. This can in fact happen easily\nwhen overloading, or when mixing named/ordered arguments.\n\nFor example:\n```lua\naddfive = argcheck{\n   {name=\"x\", type=\"number\"},\n   call =\n      function(x) -- called in case of success\n         print(string.format('%f + 5 = %f', x, x + 5))\n      end\n}\n\naddfive = argcheck{\n   {name=\"x\", type=\"number\"},\n   {name=\"msg\", type=\"string\", default=\"i know what i am doing\"},\n   overload = addfive,\n   call =\n      function(x, msg) -- called in case of success\n         print(string.format('%f + 5 = %f [msg = %s]', x, x + 5, msg))\n      end\n}\n```\n\nwill led to the error message \"argcheck rules led to ambiguous\nsituations\". One can override this behavior, with the `force` flag:\n```lua\naddfive = argcheck{\n   {name=\"x\", type=\"number\"},\n   {name=\"msg\", type=\"string\", default=\"i know what i am doing\"},\n   overload = addfive,\n   force = true,\n   call =\n      function(x, msg) -- called in case of success\n         print(string.format('%f + 5 = %f [msg = %s]', x, x+5, msg))\n      end\n}\n```\nIn this case, consider the subsequent calls:\n```lua\n\u003e addfive(5, 'hello')\n5.000000 + 5 = 10.000000 [msg = hello]\n\u003e addfive(5)\n5.000000 + 5 = 10.000000 [msg = i know what i am doing]\n```\nNote that the first function is then never called (you know what you are doing!).\n\n#### Debug\n\nAdding `debug=true` as global option will simply dump in `stdout` the\ncorresponding code for the given checking argument function. It will also\nreturn a [dot graph](http://www.graphviz.org), for better understanding of\nwhat is going on.\n\n```lua\ncheck, dotgraph = argcheck{\n   debug=true,\n   {name=\"x\", type=\"number\", default=0, help=\"the age of the captain\"},\n   {name=\"msg\", type=\"string\", help=\"a message\"}\n}\n\nlocal arg0403e9b0_1d\nlocal istype\nlocal graph\nreturn function(...)\n   local narg = select(\"#\", ...)\n   if narg \u003e= 1 and istype(select(1, ...), \"number\") then\n      if narg \u003e= 2 and istype(select(2, ...), \"string\") then\n         if narg == 2 then\n            local arg1 = select(1, ...)\n            local arg2 = select(2, ...)\n            return arg1, arg2\n         end\n      end\n   end\n   if narg \u003e= 1 and istype(select(1, ...), \"string\") then\n      if narg == 1 then\n         local arg2 = select(1, ...)\n         local arg1 = arg0403e9b0_1d\n         return arg1, arg2\n      end\n   end\n   if narg == 1 and istype(select(1, ...), \"table\") then\n      local args = select(1, ...)\n      local narg = 0\n      for k,v in pairs(args) do\n         narg = narg + 1\n      end\n      if narg \u003e= 1 and istype(args.x, \"number\") then\n         if narg \u003e= 2 and istype(args.msg, \"string\") then\n            if narg == 2 then\n               local arg1 = args.x\n               local arg2 = args.msg\n               return arg1, arg2\n            end\n         end\n      end\n      if narg \u003e= 1 and istype(args.msg, \"string\") then\n         if narg == 1 then\n            local arg2 = args.msg\n            local arg1 = arg0403e9b0_1d\n            return arg1, arg2\n         end\n      end\n   end\n   assert(graph)\n   error(string.format(\"%s\\ninvalid arguments!\", graph:usage()))\nend\n\n\u003e print(dotgraph)\ndigraph ACN {\nedge [penwidth=.3 arrowsize=0.8];\nid0403efc0 [label=\"@\" penwidth=.1 fontsize=10 style=filled fillcolor=\"#eeeeee\"];\nedge [penwidth=.3 arrowsize=0.8];\nid0403f460 [label=\"number\" penwidth=.1 fontsize=10 style=filled fillcolor=\"#eeeeee\"];\nedge [penwidth=.3 arrowsize=0.8];\nid0403f530 [label=\"string\" penwidth=.1 fontsize=10 style=filled fillcolor=\"#aaaaaa\"];\nid0403f460 -\u003e id0403f530;\nid0403efc0 -\u003e id0403f460;\nedge [penwidth=.3 arrowsize=0.8];\nid0403f7b8 [label=\"table\" penwidth=.1 fontsize=10 style=filled fillcolor=\"#eeeeee\"];\nedge [penwidth=.3 arrowsize=0.8];\nid0403f618 [label=\"number (x)\" penwidth=.1 fontsize=10 style=filled fillcolor=\"#eeeeee\"];\nedge [penwidth=.3 arrowsize=0.8];\nid04040068 [label=\"string (msg)\" penwidth=.1 fontsize=10 style=filled fillcolor=\"#aaaaaa\"];\nid0403f618 -\u003e id04040068;\nid0403f7b8 -\u003e id0403f618;\nedge [penwidth=.3 arrowsize=0.8];\nid040408b0 [label=\"string (msg)\" penwidth=.1 fontsize=10 style=filled fillcolor=\"#aaaaaa\"];\nid0403f7b8 -\u003e id040408b0;\nid0403efc0 -\u003e id0403f7b8;\nedge [penwidth=.3 arrowsize=0.8];\nid04040390 [label=\"string\" penwidth=.1 fontsize=10 style=filled fillcolor=\"#aaaaaa\"];\nid0403efc0 -\u003e id04040390;\n}\n```\n\nAs you can see, for a simple example like this one, the code is already not\nthat trivial, but handles both named and ordered arguments. Generating an\nimage out of the graph with dot (e.g. with `dot -Tpng`), leads to the\nfollowing:\n\n![](doc/tree.png)\n\nNodes with `(...)` are nodes corresponding to named arguments. Dark gray\nnodes represent valid paths in the graph. Node with a `*` suffix (after the\ntype name) are nodes which _might_ be `self` first argument of a method\n(not present in the shown example).\n\n### Advanced usage\n\nBy default, `argcheck` uses the standard `type()` Lua function to determine the type of your\narguments. In some cases, like if you are handling your own class system, you might want to\nspecify how to check types. This can be simply done by overriding the `istype()` function\navailable in the `argcheck` environment.\n```lua\nenv = require 'argcheck.env' -- retrieve argcheck environement\n\n-- this is the default type function\n-- which can be overrided by the user\nfunction env.istype(obj, typename)\n   return type(obj) == typename\nend\n```\nNote that if you change the `istype()` function, it will *not* affect previously defined\nargument checking functions: `istype()` is passed as an upvalue for each created argument\nfunction.\n\n### Real-life example\n\nSee [our cairo FFI interface](https://github.com/torch/cairo-ffi), which\nleverages `argcheck`.\n\n### Benchmark\n\nSee [the `argcheck` benchmark page](benchmark/README.md) for detailed performance report.\n","funding_links":[],"categories":["Lua"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftorch%2Fargcheck","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftorch%2Fargcheck","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftorch%2Fargcheck/lists"}