erlang-etf 1.0.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 +7 -0
- data/.gitignore +18 -0
- data/.rspec +2 -0
- data/.travis.yml +4 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +49 -0
- data/Rakefile +6 -0
- data/erlang-etf.gemspec +30 -0
- data/lib/erlang/etf.rb +40 -0
- data/lib/erlang/etf/atom.rb +46 -0
- data/lib/erlang/etf/atom_utf8.rb +44 -0
- data/lib/erlang/etf/bert.rb +74 -0
- data/lib/erlang/etf/binary.rb +44 -0
- data/lib/erlang/etf/bit_binary.rb +47 -0
- data/lib/erlang/etf/export.rb +44 -0
- data/lib/erlang/etf/extensions.rb +157 -0
- data/lib/erlang/etf/extensions/array.rb +29 -0
- data/lib/erlang/etf/extensions/big_decimal.rb +22 -0
- data/lib/erlang/etf/extensions/erlang-export.rb +26 -0
- data/lib/erlang/etf/extensions/erlang-list.rb +31 -0
- data/lib/erlang/etf/extensions/erlang-nil.rb +22 -0
- data/lib/erlang/etf/extensions/erlang-pid.rb +22 -0
- data/lib/erlang/etf/extensions/erlang-string.rb +22 -0
- data/lib/erlang/etf/extensions/erlang-tuple.rb +31 -0
- data/lib/erlang/etf/extensions/false_class.rb +28 -0
- data/lib/erlang/etf/extensions/float.rb +20 -0
- data/lib/erlang/etf/extensions/hash.rb +32 -0
- data/lib/erlang/etf/extensions/integer.rb +48 -0
- data/lib/erlang/etf/extensions/nil_class.rb +29 -0
- data/lib/erlang/etf/extensions/object.rb +24 -0
- data/lib/erlang/etf/extensions/regexp.rb +34 -0
- data/lib/erlang/etf/extensions/string.rb +35 -0
- data/lib/erlang/etf/extensions/symbol.rb +45 -0
- data/lib/erlang/etf/extensions/time.rb +29 -0
- data/lib/erlang/etf/extensions/true_class.rb +28 -0
- data/lib/erlang/etf/float.rb +57 -0
- data/lib/erlang/etf/fun.rb +67 -0
- data/lib/erlang/etf/integer.rb +29 -0
- data/lib/erlang/etf/large_big.rb +53 -0
- data/lib/erlang/etf/large_tuple.rb +55 -0
- data/lib/erlang/etf/list.rb +50 -0
- data/lib/erlang/etf/new_float.rb +33 -0
- data/lib/erlang/etf/new_fun.rb +98 -0
- data/lib/erlang/etf/new_reference.rb +59 -0
- data/lib/erlang/etf/nil.rb +23 -0
- data/lib/erlang/etf/pid.rb +45 -0
- data/lib/erlang/etf/port.rb +34 -0
- data/lib/erlang/etf/reference.rb +41 -0
- data/lib/erlang/etf/small_atom.rb +48 -0
- data/lib/erlang/etf/small_atom_utf8.rb +44 -0
- data/lib/erlang/etf/small_big.rb +59 -0
- data/lib/erlang/etf/small_integer.rb +29 -0
- data/lib/erlang/etf/small_tuple.rb +56 -0
- data/lib/erlang/etf/string.rb +46 -0
- data/lib/erlang/etf/term.rb +101 -0
- data/lib/erlang/etf/terms.rb +105 -0
- data/lib/erlang/etf/version.rb +5 -0
- data/spec/erlang/etf/atom_spec.rb +90 -0
- data/spec/erlang/etf/atom_utf8_spec.rb +90 -0
- data/spec/erlang/etf/binary_spec.rb +90 -0
- data/spec/erlang/etf/bit_binary_spec.rb +99 -0
- data/spec/erlang/etf/export_spec.rb +58 -0
- data/spec/erlang/etf/extensions/array_spec.rb +40 -0
- data/spec/erlang/etf/extensions/big_decimal_spec.rb +26 -0
- data/spec/erlang/etf/extensions/erlang-export_spec.rb +32 -0
- data/spec/erlang/etf/extensions/erlang-list_spec.rb +76 -0
- data/spec/erlang/etf/extensions/erlang-nil_spec.rb +24 -0
- data/spec/erlang/etf/extensions/erlang-pid_spec.rb +33 -0
- data/spec/erlang/etf/extensions/erlang-string_spec.rb +26 -0
- data/spec/erlang/etf/extensions/erlang-tuple_spec.rb +56 -0
- data/spec/erlang/etf/extensions/false_class_spec.rb +29 -0
- data/spec/erlang/etf/extensions/float_spec.rb +24 -0
- data/spec/erlang/etf/extensions/hash_spec.rb +90 -0
- data/spec/erlang/etf/extensions/integer_spec.rb +259 -0
- data/spec/erlang/etf/extensions/nil_class_spec.rb +29 -0
- data/spec/erlang/etf/extensions/object_spec.rb +30 -0
- data/spec/erlang/etf/extensions/regexp_spec.rb +35 -0
- data/spec/erlang/etf/extensions/string_spec.rb +43 -0
- data/spec/erlang/etf/extensions/symbol_spec.rb +64 -0
- data/spec/erlang/etf/extensions/time_spec.rb +32 -0
- data/spec/erlang/etf/extensions/true_class_spec.rb +29 -0
- data/spec/erlang/etf/float_spec.rb +92 -0
- data/spec/erlang/etf/fun_spec.rb +132 -0
- data/spec/erlang/etf/integer_spec.rb +57 -0
- data/spec/erlang/etf/large_big_spec.rb +67 -0
- data/spec/erlang/etf/large_tuple_spec.rb +119 -0
- data/spec/erlang/etf/list_spec.rb +159 -0
- data/spec/erlang/etf/new_float_spec.rb +92 -0
- data/spec/erlang/etf/new_fun_spec.rb +146 -0
- data/spec/erlang/etf/new_reference_spec.rb +60 -0
- data/spec/erlang/etf/nil_spec.rb +50 -0
- data/spec/erlang/etf/pid_spec.rb +61 -0
- data/spec/erlang/etf/port_spec.rb +58 -0
- data/spec/erlang/etf/reference_spec.rb +58 -0
- data/spec/erlang/etf/small_atom_spec.rb +90 -0
- data/spec/erlang/etf/small_atom_utf8_spec.rb +90 -0
- data/spec/erlang/etf/small_big_spec.rb +67 -0
- data/spec/erlang/etf/small_integer_spec.rb +57 -0
- data/spec/erlang/etf/small_tuple_spec.rb +112 -0
- data/spec/erlang/etf/string_spec.rb +92 -0
- data/spec/erlang/etf/term_spec.rb +27 -0
- data/spec/erlang/etf/terms_spec.rb +23 -0
- data/spec/erlang/etf_spec.rb +23 -0
- data/spec/erlang_spec.rb +77 -0
- data/spec/spec_helper.rb +7 -0
- metadata +310 -0
@@ -0,0 +1,34 @@
|
|
1
|
+
module Erlang
|
2
|
+
module ETF
|
3
|
+
|
4
|
+
#
|
5
|
+
# 1 | N | 4 | 1
|
6
|
+
# --- | ---- | -- | --------
|
7
|
+
# 102 | Node | ID | Creation
|
8
|
+
#
|
9
|
+
# Encode a port object (obtained form open_port/2). The ID is a
|
10
|
+
# node specific identifier for a local port. Port operations are
|
11
|
+
# not allowed across node boundaries. The Creation works just like
|
12
|
+
# in REFERENCE_EXT.
|
13
|
+
#
|
14
|
+
class Port
|
15
|
+
include Term
|
16
|
+
|
17
|
+
uint8 :tag, always: Terms::PORT_EXT
|
18
|
+
|
19
|
+
term :node
|
20
|
+
|
21
|
+
uint32be :id, maximum: (1 << 28) - 1
|
22
|
+
|
23
|
+
int8 :creation, maximum: (1 << 2) - 1
|
24
|
+
|
25
|
+
finalize
|
26
|
+
|
27
|
+
def initialize(node, id, creation)
|
28
|
+
@node = node
|
29
|
+
@id = id
|
30
|
+
@creation = creation
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Erlang
|
2
|
+
module ETF
|
3
|
+
|
4
|
+
#
|
5
|
+
# 1 | N | 4 | 1
|
6
|
+
# --- | ---- | -- | --------
|
7
|
+
# 101 | Node | ID | Creation
|
8
|
+
#
|
9
|
+
# Encode a reference object (an object generated with make_ref/0).
|
10
|
+
# The Node term is an encoded atom, i.e. ATOM_EXT, SMALL_ATOM_EXT
|
11
|
+
# or ATOM_CACHE_REF. The ID field contains a big-endian unsigned
|
12
|
+
# integer, but should be regarded as uninterpreted data since this
|
13
|
+
# field is node specific. Creation is a byte containing a node
|
14
|
+
# serial number that makes it possible to separate old (crashed)
|
15
|
+
# nodes from a new one.
|
16
|
+
#
|
17
|
+
# In ID, only 18 bits are significant; the rest should be 0.
|
18
|
+
# In Creation, only 2 bits are significant; the rest should be 0.
|
19
|
+
# See NEW_REFERENCE_EXT.
|
20
|
+
#
|
21
|
+
class Reference
|
22
|
+
include Term
|
23
|
+
|
24
|
+
uint8 :tag, always: Terms::REFERENCE_EXT
|
25
|
+
|
26
|
+
term :node
|
27
|
+
|
28
|
+
uint32be :id, maximum: (1 << 18) - 1
|
29
|
+
|
30
|
+
int8 :creation, maximum: (1 << 2) - 1
|
31
|
+
|
32
|
+
finalize
|
33
|
+
|
34
|
+
def initialize(node, id, creation)
|
35
|
+
@node = node
|
36
|
+
@id = id
|
37
|
+
@creation = creation
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Erlang
|
2
|
+
module ETF
|
3
|
+
|
4
|
+
#
|
5
|
+
# 1 | 1 | Len
|
6
|
+
# --- | --- | --------
|
7
|
+
# 115 | Len | AtomName
|
8
|
+
#
|
9
|
+
# An atom is stored with a 1 byte unsigned length, followed by Len
|
10
|
+
# numbers of 8 bit Latin1 characters that forms the AtomName.
|
11
|
+
# Longer atoms can be represented by ATOM_EXT.
|
12
|
+
#
|
13
|
+
# Note the SMALL_ATOM_EXT was introduced in erts version 5.7.2 and
|
14
|
+
# require an exchange of the DFLAG_SMALL_ATOM_TAGS distribution
|
15
|
+
# flag in the distribution handshake.
|
16
|
+
#
|
17
|
+
class SmallAtom
|
18
|
+
include Term
|
19
|
+
|
20
|
+
uint8 :tag, always: Terms::SMALL_ATOM_EXT
|
21
|
+
|
22
|
+
uint8 :len, default: 0 do
|
23
|
+
string :atom_name
|
24
|
+
end
|
25
|
+
|
26
|
+
undef deserialize_atom_name
|
27
|
+
def deserialize_atom_name(buffer)
|
28
|
+
self.atom_name = buffer.read(len).from_utf8_binary
|
29
|
+
end
|
30
|
+
|
31
|
+
undef serialize_atom_name
|
32
|
+
def serialize_atom_name(buffer)
|
33
|
+
buffer << atom_name.to_utf8_binary
|
34
|
+
end
|
35
|
+
|
36
|
+
finalize
|
37
|
+
|
38
|
+
def initialize(atom_name)
|
39
|
+
@atom_name = atom_name
|
40
|
+
@len = atom_name.to_s.bytesize
|
41
|
+
end
|
42
|
+
|
43
|
+
def __ruby_evolve__
|
44
|
+
atom_name.intern
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Erlang
|
2
|
+
module ETF
|
3
|
+
|
4
|
+
#
|
5
|
+
# 1 | 1 | Len
|
6
|
+
# --- | --- | --------
|
7
|
+
# 119 | Len | AtomName
|
8
|
+
#
|
9
|
+
# An atom is stored with a 1 byte unsigned length, followed by Len
|
10
|
+
# bytes containing the AtomName encoded in UTF-8. Longer atoms
|
11
|
+
# encoded in UTF-8 can be represented using ATOM_UTF8_EXT.
|
12
|
+
#
|
13
|
+
class SmallAtomUTF8
|
14
|
+
include Term
|
15
|
+
|
16
|
+
uint8 :tag, always: Terms::SMALL_ATOM_UTF8_EXT
|
17
|
+
|
18
|
+
uint8 :len, default: 0 do
|
19
|
+
string :atom_name
|
20
|
+
end
|
21
|
+
|
22
|
+
undef deserialize_atom_name
|
23
|
+
def deserialize_atom_name(buffer)
|
24
|
+
self.atom_name = buffer.read(len).from_utf8_binary
|
25
|
+
end
|
26
|
+
|
27
|
+
undef serialize_atom_name
|
28
|
+
def serialize_atom_name(buffer)
|
29
|
+
buffer << atom_name.to_utf8_binary
|
30
|
+
end
|
31
|
+
|
32
|
+
finalize
|
33
|
+
|
34
|
+
def initialize(atom_name)
|
35
|
+
@atom_name = atom_name
|
36
|
+
@len = atom_name.to_s.bytesize
|
37
|
+
end
|
38
|
+
|
39
|
+
def __ruby_evolve__
|
40
|
+
atom_name.intern
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module Erlang
|
2
|
+
module ETF
|
3
|
+
|
4
|
+
#
|
5
|
+
# 1 | 1 | 1 | n
|
6
|
+
# --- | - | ---- | ---------------
|
7
|
+
# 110 | n | Sign | d(0) ... d(n-1)
|
8
|
+
#
|
9
|
+
# Bignums are stored in unary form with a Sign byte that is 0 if
|
10
|
+
# the binum is positive and 1 if is negative. The digits are
|
11
|
+
# stored with the LSB byte stored first. To calculate the integer
|
12
|
+
# the following formula can be used:
|
13
|
+
# B = 256
|
14
|
+
# (d0*B^0 + d1*B^1 + d2*B^2 + ... d(N-1)*B^(n-1))
|
15
|
+
#
|
16
|
+
class SmallBig
|
17
|
+
include Term
|
18
|
+
|
19
|
+
uint8 :tag, always: Terms::SMALL_BIG_EXT
|
20
|
+
|
21
|
+
uint8 :n, default: 0 do
|
22
|
+
uint8 :sign, always: -> { (integer >= 0) ? 0 : 1 }
|
23
|
+
string :integer
|
24
|
+
end
|
25
|
+
|
26
|
+
undef serialize_integer
|
27
|
+
|
28
|
+
def serialize_integer(buffer)
|
29
|
+
start = buffer.bytesize
|
30
|
+
buffer << [integer.abs.to_s(2).reverse!].pack(BIN_LSB_PACK)
|
31
|
+
self.n = buffer.bytesize - start
|
32
|
+
buffer
|
33
|
+
end
|
34
|
+
|
35
|
+
undef after_serialize_n
|
36
|
+
|
37
|
+
def after_serialize_n(buffer)
|
38
|
+
buffer[@n_start, BYTES_8] = serialize_n ""
|
39
|
+
end
|
40
|
+
|
41
|
+
deserialize do |buffer|
|
42
|
+
deserialize_n(buffer)
|
43
|
+
sign, = buffer.read(BYTES_8).unpack(UINT8_PACK)
|
44
|
+
self.integer = buffer.read(n).unpack(BIN_LSB_PACK).at(0).reverse!.to_i(2) * ((sign == 0) ? 1 : -1)
|
45
|
+
self
|
46
|
+
end
|
47
|
+
|
48
|
+
finalize
|
49
|
+
|
50
|
+
def initialize(integer)
|
51
|
+
@integer = integer
|
52
|
+
end
|
53
|
+
|
54
|
+
def __ruby_evolve__
|
55
|
+
integer
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Erlang
|
2
|
+
module ETF
|
3
|
+
|
4
|
+
#
|
5
|
+
# 1 | 1
|
6
|
+
# -- | ---
|
7
|
+
# 97 | Int
|
8
|
+
#
|
9
|
+
# Unsigned 8 bit integer.
|
10
|
+
#
|
11
|
+
class SmallInteger
|
12
|
+
include Term
|
13
|
+
|
14
|
+
uint8 :tag, always: Terms::SMALL_INTEGER_EXT
|
15
|
+
|
16
|
+
uint8 :int
|
17
|
+
|
18
|
+
finalize
|
19
|
+
|
20
|
+
def initialize(int)
|
21
|
+
@int = int
|
22
|
+
end
|
23
|
+
|
24
|
+
def __ruby_evolve__
|
25
|
+
int
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module Erlang
|
2
|
+
module ETF
|
3
|
+
|
4
|
+
#
|
5
|
+
# 1 | 1 | N
|
6
|
+
# --- | ----- | --------
|
7
|
+
# 104 | Arity | Elements
|
8
|
+
#
|
9
|
+
# SMALL_TUPLE_EXT encodes a tuple. The Arity field is an unsigned
|
10
|
+
# byte that determines how many element that follows in the
|
11
|
+
# Elements section.
|
12
|
+
#
|
13
|
+
class SmallTuple
|
14
|
+
include Term
|
15
|
+
|
16
|
+
uint8 :tag, always: Terms::SMALL_TUPLE_EXT
|
17
|
+
|
18
|
+
uint8 :arity, always: -> { elements.size }
|
19
|
+
|
20
|
+
term :elements, type: :array
|
21
|
+
|
22
|
+
deserialize do |buffer|
|
23
|
+
arity, = buffer.read(BYTES_8).unpack(UINT8_PACK)
|
24
|
+
self.elements = []
|
25
|
+
arity.times do
|
26
|
+
self.elements << Terms.deserialize(buffer)
|
27
|
+
end
|
28
|
+
self
|
29
|
+
end
|
30
|
+
|
31
|
+
finalize
|
32
|
+
|
33
|
+
def initialize(elements)
|
34
|
+
@elements = elements
|
35
|
+
end
|
36
|
+
|
37
|
+
def serialize_header(buffer)
|
38
|
+
serialize_tag(buffer)
|
39
|
+
serialize_arity(buffer)
|
40
|
+
end
|
41
|
+
|
42
|
+
def bert?
|
43
|
+
elements[0].respond_to?(:atom_name) &&
|
44
|
+
elements[0].atom_name == BERT_PREFIX
|
45
|
+
end
|
46
|
+
|
47
|
+
def __ruby_evolve__
|
48
|
+
if bert?
|
49
|
+
::Erlang::ETF::BERT.evolve(self)
|
50
|
+
else
|
51
|
+
::Erlang::Tuple[*elements.map(&:__ruby_evolve__)]
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Erlang
|
2
|
+
module ETF
|
3
|
+
|
4
|
+
#
|
5
|
+
# 1 | 2 | Len
|
6
|
+
# --- | --- | ----------
|
7
|
+
# 107 | Len | Characters
|
8
|
+
#
|
9
|
+
# String does NOT have a corresponding Erlang representation, but
|
10
|
+
# is an optimization for sending lists of bytes (integer in the
|
11
|
+
# range 0-255) more efficiently over the distribution. Since the
|
12
|
+
# Length field is an unsigned 2 byte integer (big endian),
|
13
|
+
# implementations must make sure that lists longer than 65535
|
14
|
+
# elements are encoded as LIST_EXT.
|
15
|
+
#
|
16
|
+
class String
|
17
|
+
include Term
|
18
|
+
|
19
|
+
uint8 :tag, always: Terms::STRING_EXT
|
20
|
+
|
21
|
+
uint16be :len, default: 0 do
|
22
|
+
string :characters
|
23
|
+
end
|
24
|
+
|
25
|
+
undef deserialize_characters
|
26
|
+
def deserialize_characters(buffer)
|
27
|
+
self.characters = buffer.read(len).from_utf8_binary
|
28
|
+
end
|
29
|
+
|
30
|
+
undef serialize_characters
|
31
|
+
def serialize_characters(buffer)
|
32
|
+
buffer << characters.to_utf8_binary
|
33
|
+
end
|
34
|
+
|
35
|
+
finalize
|
36
|
+
|
37
|
+
def initialize(characters)
|
38
|
+
@characters = characters
|
39
|
+
end
|
40
|
+
|
41
|
+
def __ruby_evolve__
|
42
|
+
::Erlang::String.new(characters)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
module Erlang
|
2
|
+
module ETF
|
3
|
+
module Term
|
4
|
+
|
5
|
+
class << self
|
6
|
+
|
7
|
+
# Extends the including class with +ClassMethods+.
|
8
|
+
#
|
9
|
+
# @param [Class] subclass the inheriting class
|
10
|
+
def included(base)
|
11
|
+
super
|
12
|
+
|
13
|
+
base.send(:include, ::Binary::Protocol)
|
14
|
+
base.extend ClassMethods
|
15
|
+
end
|
16
|
+
|
17
|
+
private :included
|
18
|
+
end
|
19
|
+
|
20
|
+
BERT_PREFIX = "bert".freeze
|
21
|
+
|
22
|
+
BIN_LSB_PACK = 'b*'.freeze
|
23
|
+
BIN_MSB_PACK = 'B*'.freeze
|
24
|
+
|
25
|
+
module ClassMethods
|
26
|
+
|
27
|
+
def term(name, options = {})
|
28
|
+
if options.key?(:always)
|
29
|
+
__define_always__(name, options[:always])
|
30
|
+
else
|
31
|
+
if options.key?(:default)
|
32
|
+
__define_default__(name, options[:default])
|
33
|
+
else
|
34
|
+
attr_accessor name
|
35
|
+
end
|
36
|
+
|
37
|
+
if options[:type] == :array
|
38
|
+
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
39
|
+
def deserialize_#{name}(buffer)
|
40
|
+
raise NotImplementedError
|
41
|
+
end
|
42
|
+
RUBY
|
43
|
+
else
|
44
|
+
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
45
|
+
def deserialize_#{name}(buffer)
|
46
|
+
self.#{name} = Terms.deserialize(buffer)
|
47
|
+
end
|
48
|
+
RUBY
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
if options[:type] == :array
|
53
|
+
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
54
|
+
def serialize_#{name}(buffer)
|
55
|
+
#{name}.each do |term|
|
56
|
+
term.serialize(buffer)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
RUBY
|
60
|
+
else
|
61
|
+
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
62
|
+
def serialize_#{name}(buffer)
|
63
|
+
#{name}.serialize(buffer)
|
64
|
+
end
|
65
|
+
RUBY
|
66
|
+
end
|
67
|
+
|
68
|
+
serialization << :"serialize_#{name}"
|
69
|
+
fields << name
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
def ==(other)
|
75
|
+
self.class === other &&
|
76
|
+
self.class.fields.all? do |field|
|
77
|
+
__send__(field) == other.__send__(field)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def __erlang_type__
|
82
|
+
word = self.class.name.split('::').last.dup
|
83
|
+
word.gsub!('::', '/')
|
84
|
+
word.gsub!(/(?:([A-Za-z\d])|^)(UTF8)(?=\b|[^a-z])/) { "#{$1}#{$1 && '_'}#{$2.downcase}" }
|
85
|
+
word.gsub!(/([A-Z\d]+)([A-Z][a-z])/,'\1_\2')
|
86
|
+
word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
|
87
|
+
word.tr!("-", "_")
|
88
|
+
word.downcase!
|
89
|
+
word.intern
|
90
|
+
end
|
91
|
+
|
92
|
+
def __erlang_evolve__
|
93
|
+
self
|
94
|
+
end
|
95
|
+
|
96
|
+
def __ruby_evolve__
|
97
|
+
self
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|