syntheticore-perlize 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. data/README.textile +70 -0
  2. data/perlize.rb +216 -0
  3. metadata +54 -0
data/README.textile ADDED
@@ -0,0 +1,70 @@
1
+ h3. The Ruby perlizer
2
+
3
+ This module implements some of the cooler features
4
+ of Perl6 in Ruby, like topics, junctions and hyperoperators.
5
+ Extremely hackish currently, needs to be generalized
6
+ somewhat in the future.
7
+
8
+ Currently you can do the following things:
9
+
10
+
11
+ h3. Topicalization
12
+
13
+ <pre>
14
+ <code>
15
+ doubles = [1,2,3].map{ $__ * 2 }
16
+ </code>
17
+ </pre>
18
+
19
+ The topic variable works with most iterators and can also be
20
+ explicitly set using
21
+ <pre>
22
+ <code>
23
+ given object_with_long_name do
24
+ $__.foo
25
+ $__.bar
26
+ $__.foobar
27
+ end
28
+ </code>
29
+ </pre>
30
+
31
+
32
+ h3. Junctions
33
+
34
+ A junction is the composition of multiple values into one,
35
+ the individual values being bound by a logical relation.
36
+
37
+ <pre>
38
+ <code>
39
+ 5 < 2|4|6 #=> true
40
+ 5 < 2&4&6 #=> false
41
+ 5 == 1|5|9 #=> true
42
+ 2|3 < 3&4&5 #=> true
43
+ </code>
44
+ </pre>
45
+
46
+ Junctions can also be created using the all() and any() methods
47
+ from several arguments. Iterating through a junctions does
48
+ that in parallel.
49
+ <pre>
50
+ <code>
51
+ all(1,2,3,4,5).each{ puts $__ }
52
+ #=>
53
+ 3
54
+ 5
55
+ 2
56
+ 1
57
+ 4
58
+ </code>
59
+ </pre>
60
+
61
+
62
+ h3. Hyperoperators
63
+
64
+ <pre>
65
+ <code>
66
+ sum = [1,2,3]._(:+) #=> 6
67
+ fact = (1..9)._(:*) #=> 362880
68
+ [1,2,3]._(:+, [3,2,1]) #=> [4,4,4]
69
+ </code>
70
+ </pre>
data/perlize.rb ADDED
@@ -0,0 +1,216 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Created by Björn Breitgoff on 17.7.2008.
4
+ #
5
+ # Implements some of the cooler features of Perl6
6
+ # in Ruby, like topics, junctions and hyperoperators.
7
+ # Extremely hackish currently, needs to be generalized
8
+ # somewhat in the future
9
+
10
+
11
+
12
+ ###------------ Topicalization ------------###
13
+
14
+ class Module
15
+ def _topicalize_ *meths
16
+ for meth in meths
17
+ class_eval "
18
+ alias __#{meth} #{meth}
19
+ def #{meth}
20
+ self.__#{meth} do |arg|
21
+ $_2 = arg if $_1
22
+ $_1 = arg if $_1.nil?
23
+ $__ = [$_1, $_2].compact.last
24
+ return_value = yield *arg
25
+ $_1 = nil if $_2.nil?
26
+ $_2 = nil
27
+ $__ = [$_1, $_2].compact.last
28
+ return_value
29
+ end
30
+ end
31
+ "
32
+ end
33
+ end
34
+ end
35
+
36
+ def given o
37
+ $__ = o
38
+ yield
39
+ end
40
+
41
+ class Array
42
+ _topicalize_ *%w(each map select sort_by any? all?)
43
+ end
44
+
45
+ class Range
46
+ _topicalize_ *%w(each map select sort_by any? all?)
47
+ end
48
+
49
+ class Integer
50
+ _topicalize_ *%w(times step upto downto)
51
+ end
52
+
53
+
54
+
55
+
56
+ ###------------ Hyper and reduction operators ------------###
57
+
58
+ module Enumerable
59
+ def _ op, enum=nil
60
+ if enum
61
+ zip(enum).map{|i,j| i && j ? eval("#{i}.#{op} #{j}") : nil }.compact
62
+ else
63
+ eval "inject{|a,b| a.#{op} b }"
64
+ end
65
+ end
66
+ end
67
+
68
+
69
+
70
+
71
+ ###------------ Junctions ------------###
72
+
73
+ class Junction
74
+ attr_reader :operator, :objects
75
+ def initialize( operator, *objs )
76
+ @operator = operator
77
+ @objects = objs
78
+ end
79
+
80
+ def & o
81
+ raise "You cannot mix junction types" if @operator == :or or (o.is_a?(Junction) and o.operator != @operator)
82
+ @objects << (o.is_a?(Junction) ? o.objects : o)
83
+ @objects.flatten!
84
+ self
85
+ end
86
+
87
+ def | o
88
+ raise "You cannot mix junction types" if @operator == :and or (o.is_a?(Junction) and o.operator != @operator)
89
+ @objects << (o.is_a?(Junction) ? o.objects : o)
90
+ @objects.flatten!
91
+ self
92
+ end
93
+
94
+ def method_missing( meth, *args )
95
+ Junction.define_operator meth
96
+ send meth, *args
97
+ end
98
+
99
+ # XXX define as method_missing
100
+ def Junction.define_operator op
101
+ class_eval "
102
+ def #{op}( arg, direction=:normal )
103
+ if arg.is_a? Junction
104
+ case @operator
105
+ when :and
106
+ @objects.all?{ $__.#{op} arg }
107
+ when :or
108
+ @objects.any?{ $__.#{op} arg }
109
+ end
110
+ else
111
+ value = (@operator == :and)
112
+ for obj in @objects
113
+ case @operator
114
+ when :and
115
+ if direction == :normal
116
+ value = (value and (obj.#{op} arg))
117
+ else
118
+ value = (value and (arg.#{op} obj))
119
+ end
120
+ when :or
121
+ if direction == :normal
122
+ value = (value or (obj.#{op} arg))
123
+ else
124
+ value = (value or (arg.#{op} obj))
125
+ end
126
+ return value if value
127
+ end
128
+ end
129
+ return value
130
+ end
131
+ end
132
+ "
133
+ end
134
+ define_operator "=="
135
+ define_operator "<"
136
+ define_operator ">"
137
+
138
+ def each
139
+ threads = []
140
+ @objects.each do |obj|
141
+ threads << Thread.start(obj){|o| yield o }
142
+ end
143
+ threads.each{|t| t.join }
144
+ self
145
+ end
146
+ _topicalize_ 'each'
147
+
148
+ def to_s
149
+ "Junction: " + @objects.join(" #{@operator.to_s} ")
150
+ end
151
+ end
152
+
153
+
154
+ class Module
155
+ def _junctionize_ meths=nil
156
+ class_eval "
157
+ def & o
158
+ Junction.new( :and, self, o )
159
+ end
160
+
161
+ def | o
162
+ Junction.new( :or, self, o )
163
+ end
164
+ "
165
+ suitable_methods = meths || %w(== < > <= >=)
166
+ methods = public_instance_methods & suitable_methods
167
+ #module_methods = public_methods & suitable_methods
168
+ methods.each{ define_junction_method $__ }
169
+ #module_methods.each{ define_junction_method( $__, :class ) }
170
+ end
171
+
172
+ def define_junction_method( meth, type=:instance )
173
+ unless ["__id__", "__send__"].any?{ $__ == meth }
174
+ # convert operators to their ascii value for aliasing
175
+ internal = '__' + meth.gsub(/[~@^+-=>*<%&|\[\]]/){ $~[0][0].to_s }
176
+ class_eval "
177
+ alias :___#{internal} :#{meth}
178
+ def #{(type == :class) ? 'self.' : ''}#{meth} o
179
+ if o.is_a? Junction
180
+ o.#{meth}( self, :inverse )
181
+ else
182
+ #{type == :class ? (self.class.to_s + '::') : 'self.'}___#{internal} o
183
+ end
184
+ end
185
+ "
186
+ end
187
+ end
188
+ end
189
+
190
+ def all( *objs, &block )
191
+ j = Junction.new( :and, *objs )
192
+ j.each{|o| yield o } if block_given?
193
+ j
194
+ end
195
+
196
+ def any( *objs, &block )
197
+ j = Junction.new( :or, *objs )
198
+ j.each{|o| yield o } if block_given?
199
+ j
200
+ end
201
+
202
+ class Fixnum
203
+ _junctionize_
204
+ end
205
+
206
+ class Bignum
207
+ _junctionize_
208
+ end
209
+
210
+ class Float
211
+ _junctionize_
212
+ end
213
+
214
+ class String
215
+ _junctionize_
216
+ end
metadata ADDED
@@ -0,0 +1,54 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: syntheticore-perlize
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - "Bj\xC3\xB6rn Breitgoff"
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-01-28 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: Some Perl6 magic for ruby
17
+ email: breidibreit@web.de
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files: []
23
+
24
+ files:
25
+ - README.textile
26
+ - perlize.rb
27
+ has_rdoc: false
28
+ homepage: http://github.com/syntheticore/perlize
29
+ post_install_message:
30
+ rdoc_options: []
31
+
32
+ require_paths:
33
+ - .
34
+ required_ruby_version: !ruby/object:Gem::Requirement
35
+ requirements:
36
+ - - ">="
37
+ - !ruby/object:Gem::Version
38
+ version: "0"
39
+ version:
40
+ required_rubygems_version: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ version: "0"
45
+ version:
46
+ requirements: []
47
+
48
+ rubyforge_project:
49
+ rubygems_version: 1.2.0
50
+ signing_key:
51
+ specification_version: 2
52
+ summary: Some Perl6 magic for ruby
53
+ test_files: []
54
+