ampex 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. data/LICENSE.MIT +19 -0
  2. data/README.markdown +60 -0
  3. data/lib/ampex.rb +85 -0
  4. metadata +78 -0
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2010 Conrad Irwin <conrad.irwin@gmail.com>
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
@@ -0,0 +1,60 @@
1
+ The Ampex (`&X`) library provides a Metavariable X that can be used in conjunction with the unary ampersand to create anonymous blocks in a slightly more readable way than the default. It was inspired by the clever `Symbol#to_proc` method which handles the most common case very elegantly, and discussion with Sam Stokes who created an earlier version.
2
+
3
+ At its simplest, `&X` can be used as a drop-in replacement for `Symbol#to_proc`:
4
+
5
+ [1,2,3].map &X.to_s
6
+ # => ["1", "2", "3"]
7
+
8
+ However the real strength in the library comes from allowing you to call methods with arguments:
9
+
10
+ [1,"2",3].select &X.is_a?(String)
11
+ # => ["2"]
12
+
13
+ And, as everything in ruby is a method, create readable expressions without the noise of a one-argument block:
14
+
15
+ [{1 => 2}, {1 => 3}].map &X[1]
16
+ # => [2, 3]
17
+
18
+ [1,2,3].map &-X
19
+ # => [-1, -2, -3]
20
+
21
+ ["a", "b", "c"].map &(X * 2)
22
+ # => ["aa", "bb", "cc"]
23
+
24
+ As an added bonus, the effect is transitive — you can chain method calls:
25
+
26
+ [1, 2, 3].map &X.to_f.to_s
27
+ # => ["1.0", "2.0", "3.0"]
28
+
29
+ There are two things to watch out for:
30
+
31
+ Firstly, `&X` can only appear on the left:
32
+
33
+ [1, 2, 3].map &(X + 1)
34
+ # => [2, 3, 4]
35
+
36
+ [1, 2, 3].map &(1 + X) # WRONG
37
+ # => TypeError, "coerce must return [x, y]"
38
+
39
+ [[1],[2]].map &X.concat([2])
40
+ # => [[1, 2], [2, 2]]
41
+
42
+ [[1],[2]].map &[2].concat(X) # WRONG
43
+ # => TypeError, "Metavariable#to_ary should return Array"
44
+
45
+ Secondly, other arguments or operands will only be evaluated once, and not every time:
46
+
47
+ i = 0
48
+ [1, 2].map &(X + (i += 1)) # WRONG
49
+ # => [2, 3]
50
+
51
+ i = 0
52
+ [1, 2].map{ |x| x + (i += 1) }
53
+ # => [2, 4]
54
+
55
+
56
+ For bug-fixes or enhancements, please contact the author: Conrad Irwin <conrad.irwin@gmail.com>
57
+
58
+ For an up-to-date version, try http://github.com/rapportive-oss/ampex
59
+
60
+ This library is copyrighted under the MIT license, see LICENSE.MIT for details.
@@ -0,0 +1,85 @@
1
+ require 'blankslate'
2
+
3
+ # Copyright 2010 Conrad Irwin <conrad.irwin@gmail.com> MIT License
4
+ #
5
+ # For detailed usage notes, please see README.markdown
6
+ #
7
+ class Metavariable < BlankSlate
8
+ def initialize(parent=nil, &block)
9
+ @block = block
10
+ @parent = parent
11
+ end
12
+
13
+ def method_missing(name, *args, &block)
14
+ Metavariable.new(self) { |x| x.send(name, *args, &block) }
15
+ end
16
+
17
+ def to_proc
18
+ lambda do |x|
19
+ if @block
20
+ x = @parent.to_proc.call(x) if @parent
21
+ @block.call x
22
+ else
23
+ x
24
+ end
25
+ end
26
+ end
27
+
28
+ def metavariable_precedence
29
+ @parent unless @block
30
+ end
31
+ end
32
+
33
+ class CallByName < BlankSlate
34
+ def initialize(obj, parent=nil, name=nil, args=nil, block=nil)
35
+ @obj = obj
36
+ @parent = parent
37
+ @name = name
38
+ @args = args
39
+ @block = block
40
+ end
41
+
42
+ def method_missing(name, *args, &block)
43
+ CallByName.new(nil, self, name, args, block)
44
+ end
45
+
46
+ def unwind_callbyname(*args)
47
+ provided.map{|x| Metavariable === x ? called[x.metavariable_precedence] : x}
48
+ if @parent
49
+ @parent.unwind_callbyname(*args).send(@name, *CallByName.merge_args(@args, args), &@block)
50
+ else
51
+ @obj
52
+ end
53
+ end
54
+
55
+ def to_proc
56
+ if @parent
57
+ lambda { |*args| unwind_callbyname(*args) }
58
+ else
59
+ lambda { |*args| @obj }
60
+ end
61
+ end
62
+
63
+ def self.merge_args(provided, called)
64
+ end
65
+ end
66
+
67
+
68
+ class Regexp
69
+ def [](obj)
70
+ CallByName.new(obj)
71
+ end
72
+ end
73
+
74
+ module Kernel
75
+ def X
76
+ Metavariable.new(0)
77
+ end
78
+ end
79
+
80
+ K = Metavariable.new(0)
81
+ V = Metavariable.new(1)
82
+ W = Regexp.new""
83
+ X =
84
+ Y = Metavariable.new(1)
85
+ Z = Metavariable.new(2)
metadata ADDED
@@ -0,0 +1,78 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ampex
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 2
9
+ version: 0.0.2
10
+ platform: ruby
11
+ authors:
12
+ - Conrad Irwin
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-11-17 00:00:00 +00:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: blankslate
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 0
30
+ version: "0"
31
+ type: :runtime
32
+ version_requirements: *id001
33
+ description: Why would you want to write { |x| x['one'] } when you can write &X['one'], why indeed.
34
+ email: conrad.irwin@gmail.com
35
+ executables: []
36
+
37
+ extensions: []
38
+
39
+ extra_rdoc_files: []
40
+
41
+ files:
42
+ - lib/ampex.rb
43
+ - README.markdown
44
+ - LICENSE.MIT
45
+ has_rdoc: true
46
+ homepage: http://github.com/rapportive-oss/ampex
47
+ licenses: []
48
+
49
+ post_install_message:
50
+ rdoc_options: []
51
+
52
+ require_paths:
53
+ - lib
54
+ required_ruby_version: !ruby/object:Gem::Requirement
55
+ none: false
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ segments:
60
+ - 0
61
+ version: "0"
62
+ required_rubygems_version: !ruby/object:Gem::Requirement
63
+ none: false
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ segments:
68
+ - 0
69
+ version: "0"
70
+ requirements: []
71
+
72
+ rubyforge_project:
73
+ rubygems_version: 1.3.7
74
+ signing_key:
75
+ specification_version: 3
76
+ summary: Provides a meta-variable X which can be used to create procs more prettily
77
+ test_files: []
78
+