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.
- data/README.textile +70 -0
- data/perlize.rb +216 -0
- 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
|
+
|