Skip to content

Commit

Permalink
Add support for OTP 23 new_pid, new_port, and newer_reference. Defaul…
Browse files Browse the repository at this point in the history
…t to UTF-8 atoms as of OTP 23.
  • Loading branch information
potatosalad committed Aug 5, 2019
1 parent a3eaa3d commit 8d47e15
Show file tree
Hide file tree
Showing 14 changed files with 207 additions and 375 deletions.
2 changes: 1 addition & 1 deletion .ruby-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.4.1
2.6.3
4 changes: 2 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ env:
- RUBYOPT="-W0"

rvm:
- 2.4.1
- 2.6.3

notifications:
email: false

before_install:
- "gem install bundler -v 1.15.1"
- "gem install bundler -v 2.0.2"
4 changes: 2 additions & 2 deletions erlang-terms.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Gem::Specification.new do |spec|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
spec.require_paths = ["lib"]

spec.add_development_dependency "bundler", "~> 1.15"
spec.add_development_dependency "rake", "~> 12.0"
spec.add_development_dependency "bundler", "~> 2.0"
spec.add_development_dependency "rake", "~> 12.3"
spec.add_development_dependency "minitest"
end
12 changes: 6 additions & 6 deletions lib/erlang/atom.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@ class Atom
class << self
# Create a new `Atom` populated with the given `data` and `utf8` flag.
# @param data [::String, Symbol, ::Enumerable, Integer] The content of the `Atom`
# @param utf8 [Boolean] Whether the `Atom` should be considered UTF-8 or not
# @param utf8 [Boolean] Whether the `Atom` should be considered UTF-8 or not (defaults to `true`)
# @return [Atom]
# @raise [ArgumentError] if `data` cannot be coerced to be a `::String`
def [](*data, utf8: false)
def [](*data, utf8: true)
return EmptyAtom if data.empty?
if data.size == 1
return data[0] if data[0].is_a?(Erlang::Atom)
Expand Down Expand Up @@ -103,7 +103,7 @@ def compare(a, b)
end

# @private
def initialize(data = ::String.new.freeze, utf8 = false)
def initialize(data = ::String.new.freeze, utf8 = true)
raise ArgumentError, 'data must be a String' if not data.is_a?(::String)
@valid_utf8, data = Erlang::Terms.utf8_encoding(data)
@printable = Erlang::Terms.printable?(data)
Expand All @@ -120,7 +120,7 @@ def initialize(data = ::String.new.freeze, utf8 = false)
@internal = @data.intern
end
valid_internal = false
if @utf8 == false and @valid_utf8 and @printable
if @utf8 == true and @valid_utf8 and @printable
begin
if @internal == eval(@internal.inspect)
valid_internal = true
Expand Down Expand Up @@ -190,8 +190,8 @@ def erlang_inspect(raw = false)
def inspect
if @valid_internal
return @internal.inspect
elsif @utf8 == true
return "Erlang::Atom[#{@data.inspect}, utf8: true]"
elsif @utf8 == false
return "Erlang::Atom[#{@data.inspect}, utf8: false]"
else
return "Erlang::Atom[#{@data.inspect}]"
end
Expand Down
10 changes: 6 additions & 4 deletions lib/erlang/float.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,11 @@ class << self
# @raise [ArgumentError] if `data` cannot be coerced to be a `::BigDecimal`
def [](data, old: false)
if data.is_a?(::String)
data = ::BigDecimal.new(data)
data = ::Kernel::BigDecimal(data)
elsif data.is_a?(::Rational)
data = ::Kernel::BigDecimal(data.to_f.to_s)
elsif not data.is_a?(::BigDecimal)
data = ::BigDecimal.new(data.to_s)
data = ::Kernel::BigDecimal(data.to_s)
end
return new(data, old)
end
Expand All @@ -63,7 +65,7 @@ def initialize(data, old)
@data = data.freeze
@old = !!old
if @old == false and @data != @data.to_f
@data = ::BigDecimal.new(@data.to_f.to_s).freeze
@data = ::Kernel::BigDecimal(@data.to_f.to_s).freeze
end
raise ArgumentError, "data cannot be positive or negative Infinity: #{data.inspect}" if @data.to_s.include?("Infinity")
end
Expand Down Expand Up @@ -189,7 +191,7 @@ def marshal_dump
# @private
def marshal_load(args)
float_string, old = args
initialize(::BigDecimal.new(float_string), old)
initialize(::Kernel::BigDecimal(float_string), old)
__send__(:immutable!)
return self
end
Expand Down
39 changes: 31 additions & 8 deletions lib/erlang/pid.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ module Erlang
#
# Erlang::Pid["nonode@nohost", 38, 0, 0]
# # => Erlang::Pid[:"nonode@nohost", 38, 0, 0]
# Erlang::Pid["nonode@nohost", 38, 0, 0, new_pid: false]
# # => Erlang::Pid[:"nonode@nohost", 38, 0, 0, new_pid: false]
#
class Pid
include Erlang::Term
Expand All @@ -26,16 +28,21 @@ class Pid
# @return [Integer]
attr_reader :creation

# Return true if this `Pid` is a new pid
# @return [Boolean]
attr_reader :new_pid

class << self
# Create a new `Pid` populated with the given `node`, `id`, `serial`, and `creation`.
# @param node [Atom, Symbol] The node atom
# @param id [Integer] The id as a non-negative integer
# @param serial [Integer] The serial time as a non-negative integer
# @param creation [Integer] The creation time as a non-negative integer
# @param new_pid [Boolean] Whether the new pid format is used or not (defaults to `true`)
# @return [Pid]
# @raise [ArgumentError] if `node` is not an `Atom` or one of `id`, `serial`, or `creation` are not non-negative `Integer`s
def [](node, id, serial = 0, creation = 0)
return new(node, id, serial, creation)
def [](node, id, serial = 0, creation = 0, new_pid: true)
return new(node, id, serial, creation, new_pid)
end

# Compares `a` and `b` and returns whether they are less than,
Expand All @@ -60,14 +67,15 @@ def compare(a, b)
end

# @private
def initialize(node, id, serial = 0, creation = 0)
def initialize(node, id, serial = 0, creation = 0, new_pid = true)
raise ArgumentError, 'id must be a non-negative Integer' if not id.is_a?(::Integer) or id < 0
raise ArgumentError, 'serial must be a non-negative Integer' if not serial.is_a?(::Integer) or serial < 0
raise ArgumentError, 'creation must be a non-negative Integer' if not creation.is_a?(::Integer) or creation < 0
@node = Erlang::Atom[node]
@id = id.freeze
@serial = serial.freeze
@creation = creation.freeze
@new_pid = !!new_pid
end

# @private
Expand All @@ -93,11 +101,20 @@ def eql?(other)
end
alias :== :eql?

# Return true if this `Pid` is a new pid
#
# @return [Boolean]
def new_pid?
return @new_pid
end

# Return the contents of this `Pid` as a Erlang-readable `::String`.
#
# @example
# Erlang::Pid["nonode@nohost", 38, 0, 0].erlang_inspect
# # => "{'pid','nonode@nohost',38,0,0}"
# Erlang::Pid["nonode@nohost", 38, 0, 0, new_pid: false].erlang_inspect
# # => "{'pid','nonode@nohost',38,0,0,'false'}"
#
# @return [::String]
def erlang_inspect(raw = false)
Expand All @@ -106,26 +123,32 @@ def erlang_inspect(raw = false)
result << Erlang.inspect(Erlang.term_to_binary(self), raw: raw)
result << ')'
return result
else
elsif new_pid?
return Erlang.inspect(Erlang::Tuple[:pid, node, id, serial, creation], raw: raw)
else
return Erlang.inspect(Erlang::Tuple[:pid, node, id, serial, creation, new_pid], raw: raw)
end
end

# @return [::String] the nicely formatted version of the `Pid`.
def inspect
return "Erlang::Pid[#{node.inspect}, #{id.inspect}, #{serial.inspect}, #{creation.inspect}]"
if new_pid?
return "Erlang::Pid[#{node.inspect}, #{id.inspect}, #{serial.inspect}, #{creation.inspect}]"
else
return "Erlang::Pid[#{node.inspect}, #{id.inspect}, #{serial.inspect}, #{creation.inspect}, new_pid: #{new_pid.inspect}]"
end
end

# @return [::Array]
# @private
def marshal_dump
return [@node, @id, @serial, @creation]
return [@node, @id, @serial, @creation, @new_pid]
end

# @private
def marshal_load(args)
node, id, serial, creation = args
initialize(node, id, serial, creation)
node, id, serial, creation, new_pid = args
initialize(node, id, serial, creation, new_pid)
__send__(:immutable!)
return self
end
Expand Down
39 changes: 31 additions & 8 deletions lib/erlang/port.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ module Erlang
#
# Erlang::Port["nonode@nohost", 100, 1]
# # => Erlang::Port[:"nonode@nohost", 100, 1]
# Erlang::Port["nonode@nohost", 100, 1, new_port: false]
# # => Erlang::Port[:"nonode@nohost", 100, 1, new_port: false]
#
class Port
include Erlang::Term
Expand All @@ -22,15 +24,20 @@ class Port
# @return [Integer]
attr_reader :creation

# Return true if this `Port` is a new port
# @return [Boolean]
attr_reader :new_port

class << self
# Create a new `Port` populated with the given `node`, `id`, and `creation`.
# @param node [Atom, Symbol] The node atom
# @param id [Integer] The id as a non-negative integer
# @param creation [Integer] The creation time as a non-negative integer
# @param new_port [Boolean] Whether the new port format is used or not (defaults to `true`)
# @return [Port]
# @raise [ArgumentError] if `node` is not an `Atom` or `id` or `creation` are not non-negative `Integer`s
def [](node, id, creation = 0)
return new(node, id, creation)
def [](node, id, creation = 0, new_port: true)
return new(node, id, creation, new_port)
end

# Compares `a` and `b` and returns whether they are less than,
Expand All @@ -53,12 +60,13 @@ def compare(a, b)
end

# @private
def initialize(node, id, creation = 0)
def initialize(node, id, creation = 0, new_port = true)
raise ArgumentError, 'id must be a non-negative Integer' if not id.is_a?(::Integer) or id < 0
raise ArgumentError, 'creation must be a non-negative Integer' if not creation.is_a?(::Integer) or creation < 0
@node = Erlang::Atom[node]
@id = id.freeze
@creation = creation.freeze
@new_port = !!new_port
end

# @private
Expand All @@ -83,11 +91,20 @@ def eql?(other)
end
alias :== :eql?

# Return true if this `Port` is a new port
#
# @return [Boolean]
def new_port?
return @new_port
end

# Return the contents of this `Port` as a Erlang-readable `::String`.
#
# @example
# Erlang::Port["nonode@nohost", 100, 1].erlang_inspect
# # => "{'port','nonode@nohost',100,1}"
# Erlang::Port["nonode@nohost", 100, 1, new_port: false].erlang_inspect
# # => "{'port','nonode@nohost',100,1,'false'}"
#
# @return [::String]
def erlang_inspect(raw = false)
Expand All @@ -96,26 +113,32 @@ def erlang_inspect(raw = false)
result << Erlang.inspect(Erlang.term_to_binary(self), raw: raw)
result << ')'
return result
else
elsif new_port?
return Erlang.inspect(Erlang::Tuple[:port, node, id, creation], raw: raw)
else
return Erlang.inspect(Erlang::Tuple[:port, node, id, creation, new_port], raw: raw)
end
end

# @return [::String] the nicely formatted version of the `Port`.
def inspect
return "Erlang::Port[#{node.inspect}, #{id.inspect}, #{creation.inspect}]"
if new_port?
return "Erlang::Port[#{node.inspect}, #{id.inspect}, #{creation.inspect}]"
else
return "Erlang::Port[#{node.inspect}, #{id.inspect}, #{creation.inspect}, new_port: #{new_port.inspect}]"
end
end

# @return [::Array]
# @private
def marshal_dump
return [@node, @id, @creation]
return [@node, @id, @creation, @new_port]
end

# @private
def marshal_load(args)
node, id, creation = args
initialize(node, id, creation)
node, id, creation, new_port = args
initialize(node, id, creation, new_port)
__send__(:immutable!)
return self
end
Expand Down

0 comments on commit 8d47e15

Please sign in to comment.