syntheticore-perlize 0.1.4 → 0.1.5
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 +55 -25
- data/perlize.rb +98 -46
- metadata +4 -4
data/README.textile
CHANGED
@@ -1,9 +1,8 @@
|
|
1
1
|
h3. The Ruby perlizer
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
somewhat in the future.
|
3
|
+
Implements some of the coolest features of Perl6 in Ruby.
|
4
|
+
Extremely hackish currently, needs to be generalized
|
5
|
+
somewhat in the future
|
7
6
|
|
8
7
|
Currently you can do the following things:
|
9
8
|
|
@@ -16,17 +15,8 @@ h3. Topicalization
|
|
16
15
|
</code>
|
17
16
|
</pre>
|
18
17
|
|
19
|
-
The topic variable works with most iterators
|
20
|
-
|
21
|
-
<pre>
|
22
|
-
<code>
|
23
|
-
given object_with_long_name do
|
24
|
-
$__.foo
|
25
|
-
$__.bar
|
26
|
-
$__.foobar
|
27
|
-
end
|
28
|
-
</code>
|
29
|
-
</pre>
|
18
|
+
The topic variable works with most common iterators.
|
19
|
+
Topicalization is unfortunately not thread-safe!
|
30
20
|
|
31
21
|
|
32
22
|
h3. Junctions
|
@@ -48,13 +38,9 @@ from several arguments. Iterating through a junctions does
|
|
48
38
|
that in parallel.
|
49
39
|
<pre>
|
50
40
|
<code>
|
51
|
-
all(1,2,3,4,5).each{
|
41
|
+
all(1,2,3,4,5).each{|n| print n }
|
52
42
|
# prints:
|
53
|
-
|
54
|
-
5
|
55
|
-
2
|
56
|
-
1
|
57
|
-
4
|
43
|
+
35214
|
58
44
|
</code>
|
59
45
|
</pre>
|
60
46
|
|
@@ -77,12 +63,56 @@ You can force the evaluation of all elements using the eager method.
|
|
77
63
|
</pre>
|
78
64
|
|
79
65
|
|
80
|
-
h3.
|
66
|
+
h3. Other niceties
|
67
|
+
|
68
|
+
In Ruby, I often write code like this
|
69
|
+
<pre>
|
70
|
+
<code>
|
71
|
+
old_dog_names = people.map{|p| p.parents }.flatten.map{|p| p.dogs }.flatten.map{|d| d.name }.uniq
|
72
|
+
</code>
|
73
|
+
</pre>
|
74
|
+
which is alot of work to type. In Ruby 1.9 and 1.8.7 you can write:
|
75
|
+
<pre>
|
76
|
+
<code>
|
77
|
+
old_dog_names = people.map(&:parents).flatten.map(&:dogs).flatten.map(&:name).uniq
|
78
|
+
</code>
|
79
|
+
</pre>
|
80
|
+
which is already pretty beautifull. Perl6 even reserves extra syntax for that common task and lets you write
|
81
|
+
<pre>
|
82
|
+
<code>
|
83
|
+
my @old_dog_names = (@people>>.parents>>.dogs>>.name).uniq
|
84
|
+
</code>
|
85
|
+
</pre>
|
86
|
+
instead. I came up with this in Ruby:
|
87
|
+
<pre>
|
88
|
+
<code>
|
89
|
+
old_dog_names = (people>:parents>:dogs>:names).uniq
|
90
|
+
</code>
|
91
|
+
</pre>
|
92
|
+
Pretty close I think! When called with another enumerable as argument, this works like a hyperoperator
|
93
|
+
<pre>
|
94
|
+
<code>
|
95
|
+
[1,2,3]>:+, [3,2,1] #=> [4,4,4]
|
96
|
+
</code>
|
97
|
+
</pre>
|
81
98
|
|
99
|
+
Another common situation is this:
|
82
100
|
<pre>
|
83
101
|
<code>
|
84
|
-
|
85
|
-
fact = (1..9)._(:*) #=> 362880
|
86
|
-
[1,2,3]._(:+, [3,2,1]) #=> [4,4,4]
|
102
|
+
@var.foo.bar if @var and @var.foo
|
87
103
|
</code>
|
88
104
|
</pre>
|
105
|
+
where we call a method on a particular attribute only if it is defined. We can now simply write:
|
106
|
+
<pre>
|
107
|
+
<code>
|
108
|
+
@var>>:foo>>:bar
|
109
|
+
</code>
|
110
|
+
</pre>
|
111
|
+
This is somewhat like
|
112
|
+
<pre>
|
113
|
+
<code>
|
114
|
+
$var //.meth
|
115
|
+
</code>
|
116
|
+
</pre>
|
117
|
+
in Perl6.
|
118
|
+
|
data/perlize.rb
CHANGED
@@ -2,14 +2,63 @@
|
|
2
2
|
#
|
3
3
|
# Created by Björn Breitgoff on 17.7.2008.
|
4
4
|
#
|
5
|
-
# Implements some of the coolest features of Perl6
|
6
|
-
# in Ruby, like topics, junctions and hyperoperators.
|
5
|
+
# Implements some of the coolest features of Perl6 in Ruby
|
7
6
|
# Extremely hackish currently, needs to be generalized
|
8
7
|
# somewhat in the future
|
9
8
|
|
10
9
|
|
11
10
|
|
12
|
-
|
11
|
+
# Topicalization
|
12
|
+
# doubles = [1,2,3].map{ $__ * 2 }
|
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 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
|
+
# Lazy list
|
56
|
+
# results = [1,2,3].lazy.map{ $__ * 2 }.map{ $__ - 1 }
|
57
|
+
# results[2] #=> 5
|
58
|
+
# results.eager #=> [1,3,5]
|
59
|
+
# The results array is instantly available, without ever running the map methods.
|
60
|
+
# Only when you request one of its values, these are actually calculated.
|
61
|
+
# You can force the evaluation of all elements using the eager method.
|
13
62
|
|
14
63
|
class Array
|
15
64
|
def lazy
|
@@ -63,67 +112,70 @@ end
|
|
63
112
|
|
64
113
|
|
65
114
|
|
115
|
+
# Chained, flattening attribute mapping with auto-singularization
|
116
|
+
# old_dog_names = (people>:parents>:parents>:dogs>:names).uniq
|
117
|
+
# When called with another enumerable as argument, this works like a hyperoperator
|
66
118
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
return_value = yield *arg
|
80
|
-
$_1 = nil if $_2.nil?
|
81
|
-
$_2 = nil
|
82
|
-
$__ = [$_1, $_2].compact.last
|
83
|
-
return_value
|
84
|
-
end
|
85
|
-
end
|
86
|
-
"
|
119
|
+
module Enumerable
|
120
|
+
def > meth, enum=nil
|
121
|
+
return [] if empty?
|
122
|
+
unless first.respond_to? meth
|
123
|
+
meth = meth.to_s
|
124
|
+
meth[-1] = ""
|
125
|
+
meth = meth.to_sym
|
126
|
+
end
|
127
|
+
if enum
|
128
|
+
zip(enum).map{|i,j| i && j ? i.send(meth, j) : nil }.compact
|
129
|
+
else
|
130
|
+
map(&meth).flatten
|
87
131
|
end
|
88
132
|
end
|
89
133
|
end
|
90
134
|
|
91
|
-
def given o
|
92
|
-
$__ = o
|
93
|
-
yield
|
94
|
-
end
|
95
135
|
|
96
|
-
class Array
|
97
|
-
_topicalize_ *%w(each map map! select sort_by any? all?)
|
98
|
-
end
|
99
136
|
|
100
|
-
|
101
|
-
|
102
|
-
end
|
137
|
+
# obj>>:method means: call method unless obj is nil
|
138
|
+
# this is somewhat like //.meth in Perl6
|
103
139
|
|
104
|
-
class
|
105
|
-
|
140
|
+
class Object
|
141
|
+
def >> m, *args
|
142
|
+
send( m, *args ) unless nil?
|
143
|
+
end
|
106
144
|
end
|
107
145
|
|
108
146
|
|
109
147
|
|
148
|
+
# has declares attributes of a class
|
149
|
+
# It also creates a default initialize method that takes values
|
150
|
+
# in the same order as the attributes declared
|
110
151
|
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
152
|
+
class Module
|
153
|
+
def has *methods
|
154
|
+
attr_accessor *methods
|
155
|
+
class_eval "
|
156
|
+
def init(*args)
|
157
|
+
raise ArgumentError unless args.size == #{methods.size}
|
158
|
+
#{methods.inspect}.zip args do |m,a|
|
159
|
+
send( m.to_s + '=', a )
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
def initialize(*args)
|
164
|
+
init(*args)
|
165
|
+
end
|
166
|
+
"
|
120
167
|
end
|
121
168
|
end
|
122
169
|
|
123
170
|
|
124
171
|
|
125
|
-
|
126
|
-
|
172
|
+
# A junction is the composition of multiple values into one,
|
173
|
+
# the individual values being bound by a logical relation.
|
174
|
+
# 5 < 2|4|6 #=> true
|
175
|
+
# 5 < 2&4&6 #=> false
|
176
|
+
# 5 == 1|5|9 #=> true
|
177
|
+
# 2|3 < 3&4&5 #=> true
|
178
|
+
# Call _junctionize_ in your class definitions to make your own classes work in Junctions
|
127
179
|
|
128
180
|
class Junction
|
129
181
|
attr_reader :operator, :objects
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: syntheticore-perlize
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- "Bj\xC3\xB6rn Breitgoff"
|
@@ -9,11 +9,11 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-09-01 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
16
|
-
description: Some Perl6 magic for ruby
|
16
|
+
description: Some Perl6-inspired magic for ruby
|
17
17
|
email: breidibreit@web.de
|
18
18
|
executables: []
|
19
19
|
|
@@ -49,6 +49,6 @@ rubyforge_project:
|
|
49
49
|
rubygems_version: 1.2.0
|
50
50
|
signing_key:
|
51
51
|
specification_version: 2
|
52
|
-
summary: Some Perl6 magic for ruby
|
52
|
+
summary: Some Perl6-inspired magic for ruby
|
53
53
|
test_files: []
|
54
54
|
|