elixir.rb 0.0.0 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 15fb2272872a876e03b59892cfb9d9cced68d84d
4
- data.tar.gz: 333f401ceba52b483d13b4e1c461e06efe7c5b91
3
+ metadata.gz: d7b6ce1986007232752ade7baa4a4384e3ac0bcd
4
+ data.tar.gz: 8e9026a46c431118f6def60109111258db33f20a
5
5
  SHA512:
6
- metadata.gz: fd7906c50277830fca9aecccfbeea3aa0080f1b641f3391681b0adbcb827a8ea82ab215eb6538d46fa7829bf2d52f3e3a48499bcdc9fd3a886851b9de4b438e8
7
- data.tar.gz: 3468e8bcc516a445b4d44cd9ed3fee8d2d8a20dced5b59b6e9df9db13b2b96461235c0ed651766f16fddc19eb95f47647023c0b544024bb929d4a4f99feded96
6
+ metadata.gz: 682c9489155dd9a8b437eedbc7cd76907739748593309d3c82c4f8e9dfec7cafb7f5744889d5d82152b93f32bff6fc5f05ef936f941b65f2abb6a3e957e87bc4
7
+ data.tar.gz: 6c6addc1416853eb98ffaf0caa85d8c0321c1c54d8c231aeae6665cc68450294c4d799158b7474b1af1e9e230e38dc2352e6c56ca3dd771793a1d4457d616c22
@@ -1,5 +1,24 @@
1
1
  # Changelog
2
2
 
3
- ## 0.0.0 (2015-06-26)
3
+ ## 0.1.0 (2015-07-07)
4
4
 
5
- * Primordial ooze
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 implemented in Ruby. This is currently just a code spike that implements parts of Enum and Stream.
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
- ## Usage
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/enum'
56
+ require 'elixir/agent'
57
+ require 'elixir/task'
28
58
 
29
59
  include Elixir
30
60
 
31
- Enum.filter [1, 2, 3], &:odd?
32
- #=> [1, 3]
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
@@ -1,4 +1,3 @@
1
- require 'bundler/gem_tasks'
2
1
  require 'rake/testtask'
3
2
 
4
3
  Rake::TestTask.new :test do |t|
@@ -1,22 +1,26 @@
1
1
  # coding: utf-8
2
- lib = File.expand_path '../lib', File.basename(__FILE__)
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 implemented in Ruby. This is currently just a code spike with parts of Enum and Stream.'
14
- gem.description = 'A Ruby implementation of part of the Elixir standard library.'
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.add_development_dependency 'rake', '~> 10.0'
21
- gem.add_development_dependency 'minitest', '~> 5.7'
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
@@ -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
@@ -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
@@ -0,0 +1,13 @@
1
+ module Elixir
2
+ module Atom
3
+ module_function
4
+
5
+ def to_char_list symbol
6
+ symbol.to_s.chars
7
+ end
8
+
9
+ def to_string symbol
10
+ symbol.to_s
11
+ end
12
+ end
13
+ end
@@ -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
@@ -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
@@ -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, dict = {}, &block
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.step by: nth
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