erlang-terms 1.1.0 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/.coveralls.yml +1 -0
  3. data/.editorconfig +20 -0
  4. data/.gitignore +10 -18
  5. data/.ruby-gemset +1 -0
  6. data/.ruby-version +1 -0
  7. data/.travis.yml +15 -3
  8. data/.yardopts +6 -0
  9. data/CHANGELOG.md +9 -0
  10. data/Gemfile +21 -1
  11. data/LICENSE.txt +1 -1
  12. data/README.md +95 -17
  13. data/Rakefile +8 -3
  14. data/erlang-terms.gemspec +14 -11
  15. data/lib/erlang-terms.rb +1 -0
  16. data/lib/erlang/associable.rb +98 -0
  17. data/lib/erlang/atom.rb +257 -0
  18. data/lib/erlang/binary.rb +425 -0
  19. data/lib/erlang/bitstring.rb +464 -0
  20. data/lib/erlang/cons.rb +122 -0
  21. data/lib/erlang/enumerable.rb +160 -0
  22. data/lib/erlang/error.rb +4 -0
  23. data/lib/erlang/export.rb +110 -12
  24. data/lib/erlang/float.rb +201 -0
  25. data/lib/erlang/function.rb +259 -0
  26. data/lib/erlang/immutable.rb +101 -0
  27. data/lib/erlang/list.rb +1685 -24
  28. data/lib/erlang/map.rb +935 -21
  29. data/lib/erlang/nil.rb +73 -10
  30. data/lib/erlang/pid.rb +120 -18
  31. data/lib/erlang/port.rb +123 -0
  32. data/lib/erlang/reference.rb +161 -0
  33. data/lib/erlang/string.rb +175 -3
  34. data/lib/erlang/term.rb +24 -0
  35. data/lib/erlang/terms.rb +324 -8
  36. data/lib/erlang/terms/version.rb +1 -1
  37. data/lib/erlang/trie.rb +364 -0
  38. data/lib/erlang/tuple.rb +1582 -14
  39. data/lib/erlang/undefined.rb +32 -0
  40. metadata +49 -71
  41. data/spec/erlang/export_spec.rb +0 -17
  42. data/spec/erlang/list_spec.rb +0 -39
  43. data/spec/erlang/map_spec.rb +0 -24
  44. data/spec/erlang/nil_spec.rb +0 -18
  45. data/spec/erlang/pid_spec.rb +0 -21
  46. data/spec/erlang/string_spec.rb +0 -11
  47. data/spec/erlang/terms_spec.rb +0 -7
  48. data/spec/erlang/tuple_spec.rb +0 -20
  49. data/spec/spec_helper.rb +0 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8ad4212bcd8edbea5fe3b917196d48759c4ad6bc
4
- data.tar.gz: be6f85104ebcbce57e7cfb20434ab1290ae77ce2
3
+ metadata.gz: 330f0b2d72a95763b12eb4e0800ce000fe082ef2
4
+ data.tar.gz: '093515a52861b5b85f231c2820b92ff255e3e131'
5
5
  SHA512:
6
- metadata.gz: 1367b7b5d0bd9d47b65540248f7189ba292d234dc1e6844729f7194e171e97589f45522444c0812e44033c1502b2a4aa3288ab97370e86cf31bb1b6a8c9b429d
7
- data.tar.gz: 0e7cf956bd8531328fed8ce033fe4bb688700b17eb520d44f326b0659e80b58fb5ac62204dff8445595097d0aea26c66c4d2b7eea9de12dbbbf3c2414b30fcbc
6
+ metadata.gz: 9eb9eeb7f97cb07e0000d6c5c56af10bf32088750f5a526ada4836ea34f8deb447abf7c0a129dbabdddbb26f2e8eed3b00f96bba3d75dc907737f2e146fb84e5
7
+ data.tar.gz: 0ab40ae9809810f16d4bfcd2c352a6fa827cd95be3a75477b78f9f47c5d7433ed875631fdcf4d9d4193314aa1cae8f6fa4ae849c41a80fea15b9329eae5696fd
@@ -0,0 +1 @@
1
+ service_name: travis-ci
@@ -0,0 +1,20 @@
1
+ # EditorConfig helps developers define and maintain consistent
2
+ # coding styles between different editors and IDEs
3
+ # editorconfig.org
4
+
5
+ root = true
6
+
7
+ [*]
8
+
9
+ # Change these settings to your own preference
10
+ indent_style = space
11
+ indent_size = 2
12
+
13
+ # We recommend you to keep these unchanged
14
+ end_of_line = lf
15
+ charset = utf-8
16
+ trim_trailing_whitespace = true
17
+ insert_final_newline = true
18
+
19
+ [*.md]
20
+ trim_trailing_whitespace = false
data/.gitignore CHANGED
@@ -1,18 +1,10 @@
1
- *.gem
2
- *.rbc
3
- .bundle
4
- .config
5
- .rvmrc
6
- .yardoc
7
- Gemfile.lock
8
- InstalledFiles
9
- _yardoc
10
- coverage
11
- doc/
12
- lib/bundler/man
13
- pkg
14
- rdoc
15
- spec/reports
16
- test/tmp
17
- test/version_tmp
18
- tmp
1
+ /.bundle/
2
+ /.minitest-perf.db
3
+ /.yardoc
4
+ /Gemfile.lock
5
+ /_yardoc/
6
+ /coverage/
7
+ /doc/
8
+ /pkg/
9
+ /spec/reports/
10
+ /tmp/
@@ -0,0 +1 @@
1
+ erlang-terms
@@ -0,0 +1 @@
1
+ 2.4.1
@@ -1,5 +1,17 @@
1
1
  language: ruby
2
+
3
+ sudo: required
4
+ dist: trusty
5
+
6
+ env:
7
+ global:
8
+ - RUBYOPT="-W0"
9
+
2
10
  rvm:
3
- - 1.9.3
4
- - 2.0.0
5
- - 2.1.1
11
+ - 2.4.1
12
+
13
+ notifications:
14
+ email: false
15
+
16
+ before_install:
17
+ - "gem install bundler -v 1.15.1"
@@ -0,0 +1,6 @@
1
+ --no-private
2
+ --main README.md
3
+ --markup markdown
4
+ -
5
+ docs/*.md
6
+ *.md
@@ -0,0 +1,9 @@
1
+ # Changelog
2
+
3
+ ## 2.0.1 (2017-06-03)
4
+
5
+ * Fixed missing requirement error.
6
+
7
+ ## 2.0.0 (2017-06-03)
8
+
9
+ * Major rewrite. Support for atom, binary, bitstring, export, float, function, list, map, nil, pid, port, reference, string, and tuple added.
data/Gemfile CHANGED
@@ -1,4 +1,24 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- # Specify your gem's dependencies in erlang-terms.gemspec
3
+ platforms :ruby do
4
+ group :development do
5
+ gem 'pry'
6
+ gem 'pry-doc'
7
+ # gem 'redcarpet'
8
+ gem 'yard'
9
+ end
10
+ end
11
+
12
+ group :test do
13
+ gem 'minitest-focus', require: false
14
+ gem 'minitest-perf', require: false
15
+ gem 'minitest-reporters', require: false
16
+ gem 'rantly', require: false
17
+ gem 'simplecov', require: false
18
+ if ENV['CI']
19
+ gem 'coveralls', require: false
20
+ end
21
+ end
22
+
23
+ # Specify your gem's dependencies in jose.gemspec
4
24
  gemspec
@@ -1,4 +1,4 @@
1
- Copyright (c) 2013 Andrew Bennett
1
+ Copyright (c) 2013-2017 Andrew Bennett
2
2
 
3
3
  MIT License
4
4
 
data/README.md CHANGED
@@ -1,15 +1,15 @@
1
1
  # Erlang::Terms
2
2
 
3
- [![Build Status](https://travis-ci.org/potatosalad/erlang-terms.png)](https://travis-ci.org/potatosalad/erlang-terms)
3
+ [![Travis](https://img.shields.io/travis/potatosalad/ruby-erlang-terms.svg?maxAge=86400)](https://travis-ci.org/potatosalad/ruby-erlang-terms) [![Coverage Status](https://coveralls.io/repos/github/potatosalad/ruby-erlang-terms/badge.svg?branch=master)](https://coveralls.io/github/potatosalad/ruby-erlang-terms?branch=master) [![Gem](https://img.shields.io/gem/v/erlang-terms.svg?maxAge=86400)](https://rubygems.org/gems/erlang-terms) [![Docs](https://img.shields.io/badge/yard-docs-blue.svg?maxAge=86400)](http://www.rubydoc.info/gems/erlang-terms) [![Inline docs](http://inch-ci.org/github/potatosalad/ruby-erlang-terms.svg?branch=master&style=shields)](http://inch-ci.org/github/potatosalad/ruby-erlang-terms)
4
4
 
5
- Includes simple classes that represent Erlang's export, list, pid, string, tuple, and map.
5
+ Includes simple immutable classes that represent Erlang's atom, binary, bitstring, compressed, export, function, list, map, nil, pid, port, reference, string, and tuple.
6
6
 
7
7
  ## Installation
8
8
 
9
9
  Add this line to your application's Gemfile:
10
10
 
11
11
  ```ruby
12
- gem 'erlang-terms', require: 'erlang/terms'
12
+ gem 'erlang-terms', '~> 2.0'
13
13
  ```
14
14
 
15
15
  And then execute:
@@ -28,7 +28,52 @@ $ gem install erlang-terms
28
28
 
29
29
  The following classes show the [Erlang](http://www.erlang.org/) representation followed by the corresponding [Ruby](http://www.ruby-lang.org/) representation.
30
30
 
31
- See [erlang-etf](https://github.com/potatosalad/erlang-etf) for more information.
31
+ See [erlang-etf](https://github.com/potatosalad/ruby-erlang-etf) for more information.
32
+
33
+ ### Erlang::Atom
34
+
35
+ ```erlang
36
+ Atom = 'test',
37
+ AtomUTF8 = 'Ω'.
38
+ ```
39
+
40
+ ```ruby
41
+ atom = Erlang::Atom[:test]
42
+ # => :test
43
+ atom_utf8 = Erlang::Atom[:Ω, utf8: true]
44
+ # => Erlang::Atom["Ω", utf8: true]
45
+ ```
46
+
47
+ ### Erlang::Binary
48
+
49
+ ```erlang
50
+ Binary0 = <<>>,
51
+ Binary1 = <<"test">>,
52
+ Binary2 = <<0,1,2>>.
53
+ ```
54
+
55
+ ```ruby
56
+ binary0 = Erlang::Binary[]
57
+ # => ""
58
+ binary1 = Erlang::Binary["test"]
59
+ # => "test"
60
+ binary2 = Erlang::Binary[0,1,2]
61
+ # => "\x00\x01\x02"
62
+ ```
63
+
64
+ ### Erlang::Bitstring
65
+
66
+ ```erlang
67
+ Bitstring0 = <<1:7>>,
68
+ Bitstring1 = <<"test",2:3>>.
69
+ ```
70
+
71
+ ```ruby
72
+ bitstring0 = Erlang::Bitstring[1, bits: 7]
73
+ # => Erlang::Bitstring[1, bits: 7]
74
+ bitstring1 = Erlang::Bitstring["test", 2, bits: 3]
75
+ # => Erlang::Bitstring[116, 101, 115, 116, 2, bits: 3]
76
+ ```
32
77
 
33
78
  ### Erlang::Export
34
79
 
@@ -40,8 +85,19 @@ Export = fun Module:Function/Arity.
40
85
  ```
41
86
 
42
87
  ```ruby
43
- export = Erlang::Export.new(:erlang, :now, 0)
44
- # => #<Erlang::Export fun erlang:now/0>
88
+ export = Erlang::Export[:erlang, :now, 0]
89
+ # => Erlang::Export[:erlang, :now, 0]
90
+ ```
91
+
92
+ ### Erlang::Float
93
+
94
+ ```erlang
95
+ Float = 1.0e12.
96
+ ```
97
+
98
+ ```ruby
99
+ float = Erlang::Float[1.0e12]
100
+ # => 1.00000000000000000000e+12
45
101
  ```
46
102
 
47
103
  ### Erlang::List
@@ -53,8 +109,8 @@ List = [a | b].
53
109
  ```
54
110
 
55
111
  ```ruby
56
- list = Erlang::List[:a].tail(:b)
57
- # => #<Erlang::List [:a | :b]">
112
+ list = Erlang::List[:a] + :b
113
+ # => Erlang::List[:a] + :b
58
114
  list.improper?
59
115
  # => true
60
116
  ```
@@ -67,7 +123,7 @@ List = [a, b].
67
123
 
68
124
  ```ruby
69
125
  list = Erlang::List[:a, :b]
70
- # => #<Erlang::List [:a, :b | []]">
126
+ # => [:a, :b]
71
127
  list.improper?
72
128
  # => false
73
129
  ```
@@ -80,7 +136,7 @@ Map = #{atom => 1}.
80
136
 
81
137
  ```ruby
82
138
  map = Erlang::Map[:atom, 1]
83
- # => #<Erlang::Map #{:atom => 1}>
139
+ # => {:atom => 1}
84
140
  ```
85
141
 
86
142
  ### Erlang::Nil
@@ -90,8 +146,8 @@ Nil = [].
90
146
  ```
91
147
 
92
148
  ```ruby
93
- erlang_nil = Erlang::Nil.new
94
- # => #<Erlang::Nil []>
149
+ erlang_nil = Erlang::Nil
150
+ # => []
95
151
  ```
96
152
 
97
153
  ### Erlang::Pid
@@ -111,8 +167,30 @@ Pid = list_to_pid("<0.100.5>").
111
167
  ```
112
168
 
113
169
  ```ruby
114
- pid = Erlang::Pid.new('node@host', 100, 5, 0)
115
- # => #<Erlang::Pid <0.100.5> @node="node@host" @creation=0>
170
+ pid = Erlang::Pid[:"node@host", 100, 5, 0]
171
+ # => Erlang::Pid[:"node@host", 100, 5, 0]
172
+ ```
173
+
174
+ ### Erlang::Port
175
+
176
+ ```erlang
177
+ Port = hd(erlang:ports()).
178
+ ```
179
+
180
+ ```ruby
181
+ port = Erlang::Port[:"nonode@nohost", 0, 0]
182
+ # => Erlang::Port[:"nonode@nohost", 0, 0]
183
+ ```
184
+
185
+ ### Erlang::Reference
186
+
187
+ ```erlang
188
+ Reference = erlang:make_ref().
189
+ ```
190
+
191
+ ```ruby
192
+ reference = Erlang::Reference[:"nonode@nohost", 0, [168, 2, 0]]
193
+ # => Erlang::Reference[:"nonode@nohost", 0, [168, 2, 0]]
116
194
  ```
117
195
 
118
196
  ### Erlang::String
@@ -122,8 +200,8 @@ String = "test".
122
200
  ```
123
201
 
124
202
  ```ruby
125
- string = Erlang::String.new("test")
126
- # => #<Erlang::String "test">
203
+ string = Erlang::String["test"]
204
+ # => Erlang::String["test"]
127
205
  ```
128
206
 
129
207
  ### Erlang::Tuple
@@ -134,7 +212,7 @@ Tuple = {atom, 1}.
134
212
 
135
213
  ```ruby
136
214
  tuple = Erlang::Tuple[:atom, 1]
137
- # => #<Erlang::Tuple {:atom, 1}>
215
+ # => Erlang::Tuple[:atom, 1]
138
216
  ```
139
217
 
140
218
  ## Contributing
data/Rakefile CHANGED
@@ -1,6 +1,11 @@
1
1
  require "bundler/gem_tasks"
2
- require "rspec/core/rake_task"
2
+ require "rake/testtask"
3
3
 
4
- RSpec::Core::RakeTask.new(:spec)
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << "test"
6
+ t.libs << "lib"
7
+ t.test_files = FileList['test/**/*_test.rb']
8
+ t.warning = false
9
+ end
5
10
 
6
- task :default => [:spec]
11
+ task :default => :test
@@ -7,20 +7,23 @@ Gem::Specification.new do |spec|
7
7
  spec.name = "erlang-terms"
8
8
  spec.version = Erlang::Terms::VERSION
9
9
  spec.authors = ["Andrew Bennett"]
10
- spec.email = ["andrew@pagodabox.com"]
11
- spec.description = %q{Includes simple classes that represent Erlang's export, list, pid, string, and tuple.}
10
+ spec.email = ["andrew@pixid.com"]
11
+
12
+ spec.description = <<-EOF
13
+ Includes simple classes that represent Erlang's atom, binary, bitstring,
14
+ compressed, export, function, list, map, nil, pid, port, reference,
15
+ string, and tuple.
16
+ EOF
12
17
  spec.summary = %q{Erlang terms represented in Ruby}
13
- spec.homepage = "https://github.com/potatosalad/erlang-terms"
18
+ spec.homepage = "https://github.com/potatosalad/ruby-erlang-terms"
14
19
  spec.license = "MIT"
15
20
 
16
- spec.files = `git ls-files`.split($/)
17
- spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
- spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
21
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
22
+ spec.bindir = "exe"
23
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
19
24
  spec.require_paths = ["lib"]
20
25
 
21
- spec.add_development_dependency "bundler", "~> 1.3"
22
- spec.add_development_dependency "pry"
23
- spec.add_development_dependency "rake"
24
- spec.add_development_dependency "rspec"
25
- spec.add_development_dependency "simplecov"
26
+ spec.add_development_dependency "bundler", "~> 1.15"
27
+ spec.add_development_dependency "rake", "~> 12.0"
28
+ spec.add_development_dependency "minitest"
26
29
  end
@@ -0,0 +1 @@
1
+ require 'erlang/terms'
@@ -0,0 +1,98 @@
1
+ module Erlang
2
+ # Including `Associable` in your container class gives it an `update_in`
3
+ # method.
4
+ #
5
+ # To mix in `Associable`, your class must implement two methods:
6
+ #
7
+ # * `fetch(index, default = (missing_default = true))`
8
+ # * `put(index, item = yield(get(index)))`
9
+ # * `get(key)`
10
+ #
11
+ # See {Tuple#fetch}, {Tuple#put}, {Map#fetch}, and {Map#put} for examples.
12
+ #
13
+ # Licensing
14
+ # =========
15
+ #
16
+ # Portions taken and modified from https://github.com/hamstergem/hamster
17
+ #
18
+ # Copyright (c) 2009-2014 Simon Harris
19
+ #
20
+ # Permission is hereby granted, free of charge, to any person obtaining
21
+ # a copy of this software and associated documentation files (the
22
+ # "Software"), to deal in the Software without restriction, including
23
+ # without limitation the rights to use, copy, modify, merge, publish,
24
+ # distribute, sublicense, and/or sell copies of the Software, and to
25
+ # permit persons to whom the Software is furnished to do so, subject to
26
+ # the following conditions:
27
+ #
28
+ # The above copyright notice and this permission notice shall be
29
+ # included in all copies or substantial portions of the Software.
30
+ #
31
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
32
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
33
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
34
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
35
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
36
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
37
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
38
+ #
39
+ module Associable
40
+ # Return a new container with a deeply nested value modified to the result
41
+ # of the given code block. When traversing the nested containers
42
+ # non-existing keys are created with empty `Hash` values.
43
+ #
44
+ # The code block receives the existing value of the deeply nested key/index
45
+ # (or `nil` if it doesn't exist). This is useful for "transforming" the
46
+ # value associated with a certain key/index.
47
+ #
48
+ # Naturally, the original container and sub-containers are left unmodified;
49
+ # new data structure copies are created along the path as needed.
50
+ #
51
+ # @example
52
+ # t = Erlang::Tuple[123, 456, 789, Erlang::Map["a" => Erlang::Tuple[5, 6, 7]]]
53
+ # t.update_in(3, "a", 1) { |value| value + 9 }
54
+ # # => Erlang::Tuple[123, 456, 789, Erlang::Map["a'" => Erlang::Tuple[5, 15, 7]]]
55
+ # map = Erlang::Map["a" => Erlang::Map["b" => Erlang::Map["c" => 42]]]
56
+ # map.update_in("a", "b", "c") { |value| value + 5 }
57
+ # # => Erlang::Map["a" => Erlang::Map["b" => Erlang::Map["c" => 47]]]
58
+ #
59
+ # @param key_path [Object(s)] List of keys/indexes which form the path to the key to be modified
60
+ # @yield [value] The previously stored value
61
+ # @yieldreturn [Object] The new value to store
62
+ # @return [Associable]
63
+ def update_in(*key_path, &block)
64
+ if key_path.empty?
65
+ raise ArgumentError, "must have at least one key in path"
66
+ end
67
+ key = key_path[0]
68
+ if key_path.size == 1
69
+ new_value = block.call(fetch(key, nil))
70
+ else
71
+ value = fetch(key, EmptyMap)
72
+ new_value = value.update_in(*key_path[1..-1], &block)
73
+ end
74
+ return put(key, new_value)
75
+ end
76
+
77
+ # Return the value of successively indexing into a collection.
78
+ # If any of the keys is not present in the collection, return `nil`.
79
+ # keys that the Erlang type doesn't understand, raises an argument error
80
+ #
81
+ # @example
82
+ # m = Erlang::Map[:a => 9, :b => Erlang::Tuple['a', 'b'], :e => nil]
83
+ # m.dig(:b, 0) # => "a"
84
+ # m.dig(:b, 5) # => nil
85
+ # m.dig(:b, 0, 0) # => nil
86
+ # m.dig(:b, :a) # ArgumentError
87
+ # @param key to fetch from the collection
88
+ # @return [Object]
89
+ def dig(key, *rest)
90
+ value = get(key)
91
+ if rest.empty? || value.nil?
92
+ return value
93
+ elsif value.respond_to?(:dig)
94
+ return value.dig(*rest)
95
+ end
96
+ end
97
+ end
98
+ end