elixir.rb 0.0.0 → 0.1.0
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +21 -2
- data/README.md +51 -5
- data/Rakefile +0 -1
- data/elixir.rb.gemspec +10 -6
- data/lib/elixir.rb +16 -0
- data/lib/elixir/agent.rb +42 -0
- data/lib/elixir/atom.rb +13 -0
- data/lib/elixir/base.rb +99 -0
- data/lib/elixir/dict.rb +87 -0
- data/lib/elixir/enum.rb +29 -5
- data/lib/elixir/file.rb +17 -0
- data/lib/elixir/float.rb +34 -0
- data/lib/elixir/integer.rb +31 -0
- data/lib/elixir/list.rb +121 -0
- data/lib/elixir/option_parser.rb +91 -0
- data/lib/elixir/path.rb +29 -0
- data/lib/elixir/range.rb +13 -0
- data/lib/elixir/set.rb +49 -0
- data/lib/elixir/stream.rb +9 -5
- data/lib/elixir/string.rb +154 -0
- data/lib/elixir/system.rb +91 -0
- data/lib/elixir/task.rb +30 -0
- data/lib/elixir/tuple.rb +23 -0
- data/lib/elixir/version.rb +32 -1
- metadata +74 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d7b6ce1986007232752ade7baa4a4384e3ac0bcd
|
4
|
+
data.tar.gz: 8e9026a46c431118f6def60109111258db33f20a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 682c9489155dd9a8b437eedbc7cd76907739748593309d3c82c4f8e9dfec7cafb7f5744889d5d82152b93f32bff6fc5f05ef936f941b65f2abb6a3e957e87bc4
|
7
|
+
data.tar.gz: 6c6addc1416853eb98ffaf0caa85d8c0321c1c54d8c231aeae6665cc68450294c4d799158b7474b1af1e9e230e38dc2352e6c56ca3dd771793a1d4457d616c22
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,24 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
-
## 0.
|
3
|
+
## 0.1.0 (2015-07-07)
|
4
4
|
|
5
|
-
|
5
|
+
A partial implementation of the following Elixir modules:
|
6
|
+
* Agent
|
7
|
+
* Atom
|
8
|
+
* Base
|
9
|
+
* Dict
|
10
|
+
* Enum
|
11
|
+
* File
|
12
|
+
* Float
|
13
|
+
* Integer
|
14
|
+
* List
|
15
|
+
* OptionParser
|
16
|
+
* Path
|
17
|
+
* Range
|
18
|
+
* Set
|
19
|
+
* Stream
|
20
|
+
* String
|
21
|
+
* System
|
22
|
+
* Task
|
23
|
+
* Tuple
|
24
|
+
* Version
|
data/README.md
CHANGED
@@ -1,6 +1,28 @@
|
|
1
1
|
# Elixir.rb
|
2
2
|
|
3
|
-
The Elixir standard library
|
3
|
+
The [Elixir](http://elixir-lang.org) standard library in [Ruby](https://www.ruby-lang.org)!
|
4
|
+
|
5
|
+
So far there are partial implementations of the following Elixir modules:
|
6
|
+
|
7
|
+
* Agent
|
8
|
+
* Atom
|
9
|
+
* Base
|
10
|
+
* Dict
|
11
|
+
* Enum
|
12
|
+
* File
|
13
|
+
* Float
|
14
|
+
* Integer
|
15
|
+
* List
|
16
|
+
* OptionParser
|
17
|
+
* Path
|
18
|
+
* Range
|
19
|
+
* Set
|
20
|
+
* Stream
|
21
|
+
* String
|
22
|
+
* System
|
23
|
+
* Task
|
24
|
+
* Tuple
|
25
|
+
* Version
|
4
26
|
|
5
27
|
## Installation
|
6
28
|
|
@@ -8,7 +30,9 @@ The Elixir standard library implemented in Ruby. This is currently just a code s
|
|
8
30
|
gem install elixir.rb
|
9
31
|
```
|
10
32
|
|
11
|
-
##
|
33
|
+
## Examples
|
34
|
+
|
35
|
+
[Stream.unfold/2](http://elixir-lang.org/docs/stable/elixir/Stream.html#unfold/2)
|
12
36
|
|
13
37
|
```ruby
|
14
38
|
require 'elixir/stream'
|
@@ -19,19 +43,41 @@ Fib = Stream.unfold [0, 1] do |a, b|
|
|
19
43
|
[a, [b, a + b]]
|
20
44
|
end
|
21
45
|
|
46
|
+
Fib.size
|
47
|
+
#=> Infinity
|
48
|
+
|
22
49
|
Fib.take 5
|
23
50
|
#=> [0, 1, 1, 2, 3]
|
24
51
|
```
|
25
52
|
|
53
|
+
[Agent](http://elixir-lang.org/docs/stable/elixir/Agent.html) and [Task](http://elixir-lang.org/docs/stable/elixir/Task.html)
|
54
|
+
|
26
55
|
```ruby
|
27
|
-
require 'elixir/
|
56
|
+
require 'elixir/agent'
|
57
|
+
require 'elixir/task'
|
28
58
|
|
29
59
|
include Elixir
|
30
60
|
|
31
|
-
|
32
|
-
#=> [
|
61
|
+
status, agent = Agent.start { 0 }
|
62
|
+
#=> [:ok, #<Concurrent::Atomic:...>]
|
63
|
+
|
64
|
+
Agent.cast(agent) { |value| value + 42 }
|
65
|
+
#=> :ok
|
66
|
+
|
67
|
+
Agent.get(agent, &:next)
|
68
|
+
#=> 43
|
69
|
+
|
70
|
+
task = Task.async ->{ sleep 0.5; Agent.get(agent, &:itself) }
|
71
|
+
#<Concurrent::IVar:...>
|
72
|
+
|
73
|
+
Task.await(task)
|
74
|
+
#=> 42
|
33
75
|
```
|
34
76
|
|
77
|
+
## Requirements
|
78
|
+
|
79
|
+
Ruby 2.2+
|
80
|
+
|
35
81
|
## Development
|
36
82
|
|
37
83
|
Install Elixir.rb and its deps:
|
data/Rakefile
CHANGED
data/elixir.rb.gemspec
CHANGED
@@ -1,22 +1,26 @@
|
|
1
1
|
# coding: utf-8
|
2
|
-
lib = File.expand_path '../lib',
|
2
|
+
lib = File.expand_path '../lib', __FILE__
|
3
3
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
|
4
5
|
require 'elixir/version'
|
5
6
|
|
6
7
|
Gem::Specification.new do |gem|
|
7
8
|
gem.name = 'elixir.rb'
|
8
9
|
gem.version = Elixir::VERSION
|
9
10
|
gem.author = 'Shannon Skipper'
|
10
|
-
gem.license = 'MIT'
|
11
11
|
gem.email = ['shannonskipper@gmail.com']
|
12
|
+
gem.license = 'MIT'
|
12
13
|
|
13
|
-
gem.summary = 'The Elixir standard library
|
14
|
-
gem.description = '
|
14
|
+
gem.summary = 'The Elixir standard library in Ruby.'
|
15
|
+
gem.description = 'An implementation of parts of the Elixir standard library in Ruby.'
|
15
16
|
gem.homepage = 'https://github.com/havenwood/elixir.rb'
|
16
17
|
|
17
18
|
gem.files = `git ls-files -z`.split("\x0").reject { |path| path.start_with? 'test' }
|
18
19
|
gem.require_paths = ['lib']
|
19
20
|
|
20
|
-
gem.
|
21
|
-
gem.
|
21
|
+
gem.add_dependency 'base32', '~> 0.3', '>= 0.3.2'
|
22
|
+
gem.add_dependency 'concurrent-ruby', '~> 0.8', '>= 0.8.0'
|
23
|
+
|
24
|
+
gem.add_development_dependency 'rake', '~> 10.4', '>= 10.4.2'
|
25
|
+
gem.add_development_dependency 'minitest', '~> 5.7', '>= 5.7.0'
|
22
26
|
end
|
data/lib/elixir.rb
CHANGED
@@ -1,5 +1,21 @@
|
|
1
|
+
require 'elixir/agent'
|
2
|
+
require 'elixir/atom'
|
3
|
+
require 'elixir/base'
|
4
|
+
require 'elixir/dict'
|
1
5
|
require 'elixir/enum'
|
6
|
+
require 'elixir/file'
|
7
|
+
require 'elixir/float'
|
8
|
+
require 'elixir/integer'
|
9
|
+
require 'elixir/list'
|
10
|
+
require 'elixir/option_parser'
|
11
|
+
require 'elixir/path'
|
12
|
+
require 'elixir/range'
|
13
|
+
require 'elixir/set'
|
2
14
|
require 'elixir/stream'
|
15
|
+
require 'elixir/string'
|
16
|
+
require 'elixir/system'
|
17
|
+
require 'elixir/task'
|
18
|
+
require 'elixir/tuple'
|
3
19
|
require 'elixir/version'
|
4
20
|
|
5
21
|
module Elixir
|
data/lib/elixir/agent.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'concurrent'
|
2
|
+
|
3
|
+
module Elixir
|
4
|
+
module Agent
|
5
|
+
module_function
|
6
|
+
|
7
|
+
def cast agent, &fun
|
8
|
+
agent.try_update do |value|
|
9
|
+
->{ fun.call value.call }
|
10
|
+
end
|
11
|
+
|
12
|
+
:ok
|
13
|
+
end
|
14
|
+
|
15
|
+
def get agent, &fun
|
16
|
+
fun.call agent.get.call
|
17
|
+
end
|
18
|
+
|
19
|
+
def get_and_update agent, &fun
|
20
|
+
old_lambda = agent.get
|
21
|
+
old_value = old_lambda.call
|
22
|
+
new_lambda = ->{ fun.call old_value }
|
23
|
+
agent.compare_and_set old_lambda, new_lambda
|
24
|
+
|
25
|
+
old_value
|
26
|
+
end
|
27
|
+
|
28
|
+
def start &fun
|
29
|
+
[:ok, Concurrent::Atomic.new(fun)]
|
30
|
+
end
|
31
|
+
|
32
|
+
def update agent, &fun
|
33
|
+
agent.update do |value|
|
34
|
+
->{ fun.call value.call }
|
35
|
+
end
|
36
|
+
|
37
|
+
:ok
|
38
|
+
end
|
39
|
+
|
40
|
+
# TODO: Timeouts and explain what's lacking in the Ruby implementation.
|
41
|
+
end
|
42
|
+
end
|
data/lib/elixir/atom.rb
ADDED
data/lib/elixir/base.rb
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
require 'base32'
|
2
|
+
require 'base64'
|
3
|
+
|
4
|
+
module Elixir
|
5
|
+
module Base
|
6
|
+
UPPERCASE = /[[:upper:]]/.freeze
|
7
|
+
LOWERCASE = /[[:lower:]]/.freeze
|
8
|
+
|
9
|
+
module_function
|
10
|
+
|
11
|
+
def decode16 string, char_case: :upper
|
12
|
+
case char_case
|
13
|
+
when :upper
|
14
|
+
return :error if string =~ LOWERCASE
|
15
|
+
when :lower
|
16
|
+
return :error if string =~ UPPERCASE
|
17
|
+
end
|
18
|
+
|
19
|
+
[:ok, [string].pack('H*')] rescue :error
|
20
|
+
end
|
21
|
+
|
22
|
+
def decode16! string, char_case: :upper
|
23
|
+
case char_case
|
24
|
+
when :upper
|
25
|
+
raise ArgumentError if string =~ LOWERCASE
|
26
|
+
when :lower
|
27
|
+
raise ArgumentError if string =~ UPPERCASE
|
28
|
+
end
|
29
|
+
|
30
|
+
[string].pack 'H*'
|
31
|
+
end
|
32
|
+
|
33
|
+
def decode32 string, char_case: :upper
|
34
|
+
case char_case
|
35
|
+
when :upper
|
36
|
+
return :error if string =~ LOWERCASE
|
37
|
+
when :lower
|
38
|
+
return :error if string =~ UPPERCASE
|
39
|
+
end
|
40
|
+
|
41
|
+
[:ok, Base32.decode(string)] rescue :error
|
42
|
+
end
|
43
|
+
|
44
|
+
def decode32! string, char_case: :upper
|
45
|
+
case char_case
|
46
|
+
when :upper
|
47
|
+
raise ArgumentError if string =~ LOWERCASE
|
48
|
+
when :lower
|
49
|
+
raise ArgumentError if string =~ UPPERCASE
|
50
|
+
end
|
51
|
+
|
52
|
+
Base32.decode string
|
53
|
+
end
|
54
|
+
|
55
|
+
def decode64 string
|
56
|
+
[:ok, Base64.strict_decode64(string)] rescue :error
|
57
|
+
end
|
58
|
+
|
59
|
+
def decode64! string
|
60
|
+
Base64.strict_decode64 string
|
61
|
+
end
|
62
|
+
|
63
|
+
def encode16 data, char_case: :upper
|
64
|
+
encoded = data.unpack('H*').first
|
65
|
+
|
66
|
+
char_case == :upper ? encoded.upcase : encoded
|
67
|
+
end
|
68
|
+
|
69
|
+
def encode32 data, char_case: :upper
|
70
|
+
encoded = Base32.encode data
|
71
|
+
|
72
|
+
char_case == :upper ? encoded.upcase : encoded
|
73
|
+
end
|
74
|
+
|
75
|
+
def encode64 data
|
76
|
+
Base64.strict_encode64(data)
|
77
|
+
end
|
78
|
+
|
79
|
+
def hex_encode32 string, char_case: :upper
|
80
|
+
# TODO
|
81
|
+
end
|
82
|
+
|
83
|
+
def hex_decode32 string, char_case: :upper
|
84
|
+
# TODO
|
85
|
+
end
|
86
|
+
|
87
|
+
def hex_decode32! string, char_case: :upper
|
88
|
+
# TODO
|
89
|
+
end
|
90
|
+
|
91
|
+
def url_decode64 string
|
92
|
+
# TODO
|
93
|
+
end
|
94
|
+
|
95
|
+
def url_decode64! string
|
96
|
+
# TODO
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
data/lib/elixir/dict.rb
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
module Elixir
|
2
|
+
module Dict
|
3
|
+
module_function
|
4
|
+
|
5
|
+
def delete list, key
|
6
|
+
list.delete key
|
7
|
+
|
8
|
+
list
|
9
|
+
end
|
10
|
+
|
11
|
+
def drop list, keys
|
12
|
+
keys.each do |key|
|
13
|
+
list.delete key
|
14
|
+
end
|
15
|
+
|
16
|
+
list
|
17
|
+
end
|
18
|
+
|
19
|
+
def equal? dict1, dict2
|
20
|
+
dict1.eql? dict2
|
21
|
+
end
|
22
|
+
|
23
|
+
def fetch dict, key
|
24
|
+
dict.fetch(key) rescue nil
|
25
|
+
end
|
26
|
+
|
27
|
+
def fetch!
|
28
|
+
dict.fetch key
|
29
|
+
end
|
30
|
+
|
31
|
+
def get dict, key, default = nil
|
32
|
+
# TODO
|
33
|
+
end
|
34
|
+
|
35
|
+
def hash_key? dict, key
|
36
|
+
# TODO
|
37
|
+
end
|
38
|
+
|
39
|
+
def keys dict
|
40
|
+
# TODO
|
41
|
+
end
|
42
|
+
|
43
|
+
def merge dict1, dict2, fun = -> _k, _v1, v2 { v2 }
|
44
|
+
# TODO
|
45
|
+
end
|
46
|
+
|
47
|
+
def pop dict, key, default = nil
|
48
|
+
# TODO
|
49
|
+
end
|
50
|
+
|
51
|
+
def put dict, key, val
|
52
|
+
# TODO
|
53
|
+
end
|
54
|
+
|
55
|
+
def put_new dict, key, val
|
56
|
+
# TODO
|
57
|
+
end
|
58
|
+
|
59
|
+
def size dict
|
60
|
+
# TODO
|
61
|
+
end
|
62
|
+
|
63
|
+
def split dict, keys
|
64
|
+
# TODO
|
65
|
+
end
|
66
|
+
|
67
|
+
def take dict, keys
|
68
|
+
# TODO
|
69
|
+
end
|
70
|
+
|
71
|
+
def to_list dict
|
72
|
+
# TODO
|
73
|
+
end
|
74
|
+
|
75
|
+
def update dict, key, initial, fun
|
76
|
+
# TODO
|
77
|
+
end
|
78
|
+
|
79
|
+
def update! dict, key, fun
|
80
|
+
# TODO
|
81
|
+
end
|
82
|
+
|
83
|
+
def values dict
|
84
|
+
# TODO
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
data/lib/elixir/enum.rb
CHANGED
@@ -15,6 +15,7 @@ module Elixir
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def chunk collection, n, step: nil, pad: nil
|
18
|
+
# TODO
|
18
19
|
end
|
19
20
|
|
20
21
|
def chunk_by collection, &block
|
@@ -37,14 +38,22 @@ module Elixir
|
|
37
38
|
collection.drop_while &block
|
38
39
|
end
|
39
40
|
|
41
|
+
def each collection, &block
|
42
|
+
collection.each &block
|
43
|
+
|
44
|
+
:ok
|
45
|
+
end
|
46
|
+
|
40
47
|
def empty? collection
|
41
48
|
collection.empty?
|
42
49
|
end
|
43
50
|
|
44
51
|
def fetch collection, n
|
52
|
+
# TODO
|
45
53
|
end
|
46
54
|
|
47
55
|
def fetch! collection, n
|
56
|
+
# TODO
|
48
57
|
end
|
49
58
|
|
50
59
|
def filter collection, &block
|
@@ -52,6 +61,7 @@ module Elixir
|
|
52
61
|
end
|
53
62
|
|
54
63
|
def filter_map collection, filter, mapper
|
64
|
+
# TODO
|
55
65
|
end
|
56
66
|
|
57
67
|
def find collection, ifnone = nil, &block
|
@@ -59,9 +69,11 @@ module Elixir
|
|
59
69
|
end
|
60
70
|
|
61
71
|
def find_index collection, &block
|
72
|
+
# TODO
|
62
73
|
end
|
63
74
|
|
64
75
|
def find_value collection, ifnone = nil, &block
|
76
|
+
# TODO
|
65
77
|
end
|
66
78
|
|
67
79
|
def flat_map collection, &block
|
@@ -69,15 +81,19 @@ module Elixir
|
|
69
81
|
end
|
70
82
|
|
71
83
|
def flat_map_reduce collection, acc, &block
|
84
|
+
# TODO
|
72
85
|
end
|
73
86
|
|
74
|
-
def group_by collection,
|
87
|
+
def group_by collection, &block
|
88
|
+
collection.group_by(&block).map { |k, v| [k.to_s.to_sym, v] }.to_h
|
75
89
|
end
|
76
90
|
|
77
91
|
def intersperse collection, element
|
92
|
+
collection.each_with_object(element).to_a.flatten 1
|
78
93
|
end
|
79
94
|
|
80
95
|
def into collection, list, transform = nil
|
96
|
+
# TODO
|
81
97
|
end
|
82
98
|
|
83
99
|
def join collection, joiner = ''
|
@@ -89,16 +105,19 @@ module Elixir
|
|
89
105
|
end
|
90
106
|
|
91
107
|
def map_join collection, joiner = '', &block
|
108
|
+
collection.map(&block).join joiner
|
92
109
|
end
|
93
110
|
|
94
111
|
def map_reduce collection, acc, &block
|
112
|
+
# TODO
|
95
113
|
end
|
96
114
|
|
97
115
|
def max collection
|
98
|
-
collection.max
|
116
|
+
collection.max or raise 'empty error'
|
99
117
|
end
|
100
118
|
|
101
119
|
def max_by collection, &block
|
120
|
+
collection.max_by &block
|
102
121
|
end
|
103
122
|
|
104
123
|
def member? collection, value
|
@@ -106,7 +125,7 @@ module Elixir
|
|
106
125
|
end
|
107
126
|
|
108
127
|
def min collection
|
109
|
-
collection.min
|
128
|
+
collection.min or raise 'empty error'
|
110
129
|
end
|
111
130
|
|
112
131
|
def min_by collection, &block
|
@@ -134,6 +153,7 @@ module Elixir
|
|
134
153
|
end
|
135
154
|
|
136
155
|
def scan collection, acc = 0, &block
|
156
|
+
# TODO
|
137
157
|
end
|
138
158
|
|
139
159
|
def shuffle collection
|
@@ -141,6 +161,7 @@ module Elixir
|
|
141
161
|
end
|
142
162
|
|
143
163
|
def slice collection, x, count = nil
|
164
|
+
# TODO
|
144
165
|
end
|
145
166
|
|
146
167
|
def sort collection, &block
|
@@ -148,13 +169,15 @@ module Elixir
|
|
148
169
|
end
|
149
170
|
|
150
171
|
def sort_by collection, mapper, sorter = nil
|
172
|
+
# TODO
|
151
173
|
end
|
152
174
|
|
153
175
|
def split collection, count
|
154
|
-
|
176
|
+
# TODO
|
155
177
|
end
|
156
178
|
|
157
179
|
def split_while collection, &block
|
180
|
+
# TODO
|
158
181
|
end
|
159
182
|
|
160
183
|
def sum collection
|
@@ -166,10 +189,11 @@ module Elixir
|
|
166
189
|
end
|
167
190
|
|
168
191
|
def take_every collection, nth
|
169
|
-
collection.
|
192
|
+
collection.each_slice(nth).map &:first
|
170
193
|
end
|
171
194
|
|
172
195
|
def take_while collection, &block
|
196
|
+
# TODO
|
173
197
|
end
|
174
198
|
|
175
199
|
def to_list collection
|