named_parameters.pl 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. #!/usr/bin/perl
  2. # Author: Daniel "Trizen" Șuteu
  3. # License: GPLv3
  4. # Date: 23 October 2015
  5. # Website: https://github.com/trizen
  6. # Code-concept for implementing the "named-parameters" feature in programming languages.
  7. =for Sidef example:
  8. func test (x, y, z) {
  9. say (x, y, z); # prints: '123'
  10. }
  11. test(1,2,3);
  12. test(1, y: 2, z: 3);
  13. test(x: 1, y: 2, z: 3);
  14. test(y: 2, z: 3, x: 1);
  15. ...
  16. =cut
  17. use 5.010;
  18. use strict;
  19. use warnings;
  20. use List::Util qw(shuffle);
  21. sub test {
  22. my @args = @_;
  23. my @vars = (\my $x, \my $y, \my $z);
  24. my %table = (
  25. x => 0,
  26. y => 1,
  27. z => 2,
  28. );
  29. my @left;
  30. my %seen;
  31. foreach my $arg (@args) {
  32. if (ref($arg) eq 'ARRAY') {
  33. if (exists $table{$arg->[0]}) {
  34. ${$vars[$table{$arg->[0]}]} = $arg->[1];
  35. undef $seen{$vars[$table{$arg->[0]}]};
  36. }
  37. else {
  38. die "No such named argument: <<$arg->[0]>>";
  39. }
  40. }
  41. else {
  42. push @left, $arg;
  43. }
  44. }
  45. foreach my $var (@vars) {
  46. next if exists $seen{$var};
  47. if (@left) {
  48. ${$var} = shift @left;
  49. }
  50. }
  51. say "$x $y $z";
  52. ($x == 1 and $y == 2 and $z == 3) or die "error!";
  53. }
  54. test(1, ['y', 2], 3);
  55. test(1, 3, ['y', 2]);
  56. test(1, ['z', 3], 2);
  57. test(1, 2, ['z', 3]);
  58. test(1, 3, ['y', 2]);
  59. test(['y', 2], 1, 3);
  60. test(['x', 1], ['z', 3], ['y', 2]);
  61. test(shuffle(['x', 1], 3, ['y', 2]));
  62. test(shuffle(['x', 1], 2, ['z', 3]));
  63. test(shuffle(1, ['y', 2], ['z', 3]));
  64. test(shuffle(['z', 3], ['x', 1], ['y', 2]));
  65. test(shuffle(['z', 3], 1, ['y', 2]));