erlang-etf 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|