@@ -337,8 +337,13 @@ defmodule Macro do
337
337
end
338
338
339
339
@ doc """
340
- Generates AST nodes for a given number of required argument variables using
341
- `Macro.var/2`.
340
+ Generates AST nodes for a given number of required argument
341
+ variables using `Macro.var/2`.
342
+
343
+ Note the arguments are not unique. If you later on want
344
+ to access this same varibles, you can invoke this function
345
+ with the same inputs. Use `generate_unique_arguments/2` to
346
+ generate a unique arguments that can't be overridden.
342
347
343
348
## Examples
344
349
@@ -349,19 +354,47 @@ defmodule Macro do
349
354
@ doc since: "1.5.0"
350
355
@ spec generate_arguments ( 0 , context :: atom ) :: [ ]
351
356
@ spec generate_arguments ( pos_integer , context ) :: [ { atom , [ ] , context } , ... ] when context: atom
352
- def generate_arguments ( amount , context )
357
+ def generate_arguments ( amount , context ) , do: generate_arguments ( amount , context , & var / 2 )
358
+
359
+ @ doc """
360
+ Generates AST nodes for a given number of required argument
361
+ variables using `Macro.unique_var/2`.
362
+
363
+ ## Examples
353
364
354
- def generate_arguments ( 0 , context ) when is_atom ( context ) , do: [ ]
365
+ iex> [var1, var2] = Macro.generate_unique_arguments(2, __MODULE__)
366
+ iex> {:arg1, [counter: c1], __MODULE__} = var1
367
+ iex> {:arg2, [counter: c2], __MODULE__} = var2
368
+ iex> is_integer(c1) and is_integer(c2)
369
+ true
370
+
371
+ """
372
+ @ doc since: "1.11.3"
373
+ @ spec generate_unique_arguments ( 0 , context :: atom ) :: [ ]
374
+ @ spec generate_unique_arguments ( pos_integer , context ) :: [
375
+ { atom , [ counter: integer ] , context } ,
376
+ ...
377
+ ]
378
+ when context: atom
379
+ def generate_unique_arguments ( amount , context ) ,
380
+ do: generate_arguments ( amount , context , & unique_var / 2 )
355
381
356
- def generate_arguments ( amount , context )
357
- when is_integer ( amount ) and amount > 0 and is_atom ( context ) do
358
- for id <- 1 .. amount , do: var ( String . to_atom ( "arg" <> Integer . to_string ( id ) ) , context )
382
+ defp generate_arguments ( 0 , context , _fun ) when is_atom ( context ) , do: [ ]
383
+
384
+ defp generate_arguments ( amount , context , fun )
385
+ when is_integer ( amount ) and amount > 0 and is_atom ( context ) do
386
+ for id <- 1 .. amount , do: fun . ( String . to_atom ( "arg" <> Integer . to_string ( id ) ) , context )
359
387
end
360
388
361
389
@ doc """
362
390
Generates an AST node representing the variable given
363
391
by the atoms `var` and `context`.
364
392
393
+ Note this variable is not unique. If you later on want
394
+ to access this same varible, you can invoke `var/2`
395
+ again with the same argument. Use `unique_var/2` to
396
+ generate a unique variable that can't be overridden.
397
+
365
398
## Examples
366
399
367
400
In order to build a variable, a context is expected.
@@ -383,6 +416,24 @@ defmodule Macro do
383
416
{ var , [ ] , context }
384
417
end
385
418
419
+ @ doc """
420
+ Generates an AST node representing a unique variable
421
+ given by the atoms `var` and `context`.
422
+
423
+ ## Examples
424
+
425
+ iex> {:foo, [counter: c], __MODULE__} = Macro.unique_var(:foo, __MODULE__)
426
+ iex> is_integer(c)
427
+ true
428
+
429
+ """
430
+ @ doc since: "1.11.3"
431
+ @ spec unique_var ( var , context ) :: { var , [ counter: integer ] , context }
432
+ when var: atom , context: atom
433
+ def unique_var ( var , context ) when is_atom ( var ) and is_atom ( context ) do
434
+ { var , [ counter: :elixir_module . next_counter ( context ) ] , context }
435
+ end
436
+
386
437
@ doc """
387
438
Performs a depth-first traversal of quoted expressions
388
439
using an accumulator.
0 commit comments