Guest User

Untitled

a guest
Jun 21st, 2018
190
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.32 KB | None | 0 0
  1. require 'blankslate'
  2.  
  3. # The Ampex library provides a metavariable X that can be used in conjunction
  4. # with the unary ampersand to create anonymous blocks in a slightly more
  5. # readable way than the default. It was inspired by the clever `Symbol#to_proc`
  6. # method which handles the most common case very elegantly, and discussion with
  7. # Sam Stokes who implemented an earlier version of the idea.
  8. #
  9. # At its simplest, &X can be used as a drop-in replacement for
  10. # `Symbol#to_proc`:
  11. #
  12. # [1,2,3].map &X.to_s
  13. # # => ["1", "2", "3"]
  14. #
  15. # However the real strength in the library comes from allowing you to call
  16. # methods:
  17. #
  18. # [1,"2",3].select &X.is_a?(String)
  19. # # => ["2"]
  20. #
  21. # And, as everything in ruby is a method, create readable expressions without
  22. # the noise of a one-argument block:
  23. #
  24. # [{1 => 2}, {1 => 3}].map &X[1]
  25. # # => [2, 3]
  26. #
  27. # [1,2,3].map &-X
  28. # # => [-1, -2, -3]
  29. #
  30. # ["a", "b", "c"].map &(X * 2)
  31. # # => ["aa", "bb", "cc"]
  32. #
  33. # As an added bonus, the effect is transitive — you can chain method calls:
  34. #
  35. # [1, 2, 3].map &X.to_f.to_s
  36. # # => ["1.0", "2.0", "3.0"]
  37. #
  38. # There are two things to watch out for:
  39. #
  40. # Firstly, &X can only appear on the left:
  41. #
  42. # [1, 2, 3].map &(X + 1)
  43. # # => [2, 3, 4]
  44. #
  45. # [1, 2, 3].map &(1 + X) # WRONG
  46. # # => TypeError, "coerce must return [x, y]"
  47. #
  48. # [[1],[2]].map &X.concat([2])
  49. # # => [[1, 2], [2, 2]]
  50. #
  51. # [[1],[2]].map &[2].concat(X) # WRONG
  52. # # => TypeError, "Metavariable#to_ary should return Array"
  53. #
  54. # Secondly, the arguments or operands will only be evaluated once, and not
  55. # every time:
  56. #
  57. # i = 0 [1, 2].map &(X + (i += 1)) # WRONG
  58. # # => [2, 3]
  59. #
  60. # i = 0 [1, 2].map{ |x| x + (i += 1) }
  61. # # => [2, 4]
  62. #
  63. # For bug-fixes or enhancements, please contact the author:
  64. # Conrad Irwin <conrad.irwin@gmail.com>
  65. #
  66. # This library is copyrighted under the MIT license, see LICENSE.MIT.
  67.  
  68. class Metavariable < BlankSlate
  69. def initialize(parent=nil, &block)
  70. @block = block
  71. @parent = parent
  72. end
  73.  
  74. def method_missing(name, *args, &block)
  75. Metavariable.new(self) { |x| x.send(name, *args, &block) }
  76. end
  77.  
  78. def to_proc
  79. lambda do |x|
  80. if @block
  81. x = @parent.to_proc.call(x) if @parent
  82. @block.call x
  83. else
  84. x
  85. end
  86. end
  87. end
  88. end
  89.  
  90. X = Metavariable.new
Add Comment
Please, Sign In to add comment