diff --git a/README.md b/README.md index 04d0ef8..1499350 100644 --- a/README.md +++ b/README.md @@ -22,11 +22,12 @@ Instances of the following Ruby classes will be automatically converted to the p * Time * Regexp -Most of these conversions work as expected with one important caveat. Arrays will be converted into tuples. To have an array converted as a list, simply prepend it with `l` like so: +To designate tuples, simply prefix an Array literal with a `t` or use the BERT::Tuple class: - [:foo, l[1, 2, 3]] + t[:foo, [1, 2, 3]] + BERT::Tuple.new([:foo, [1, 2, 3]]) -This will be converted as (in Erlang syntax): +Both of these will be converted to (in Erlang syntax): {foo, [1, 2, 3]} diff --git a/lib/bert.rb b/lib/bert.rb index 2f222c4..7a172f4 100644 --- a/lib/bert.rb +++ b/lib/bert.rb @@ -20,6 +20,14 @@ module BERT end end -def l - Erl::List +module BERT + class Tuple < Array + def inspect + "t#{super}" + end + end +end + +def t + BERT::Tuple end \ No newline at end of file diff --git a/lib/bert/decoder.rb b/lib/bert/decoder.rb index 077441c..fd4bf8f 100644 --- a/lib/bert/decoder.rb +++ b/lib/bert/decoder.rb @@ -20,6 +20,8 @@ module BERT item.to_s.to_sym when [:nil, :nil] nil + when Erl::List + item.map { |x| convert(x) } when Array case item.first when :dict @@ -37,7 +39,7 @@ module BERT options |= Regexp::MULTILINE if item[2] =~ /m/ Regexp.new(item[1], options) else - item.map { |x| convert(x) } + Tuple.new(item.map { |x| convert(x) }) end else item diff --git a/lib/bert/encoder.rb b/lib/bert/encoder.rb index 9a1083c..076501f 100644 --- a/lib/bert/encoder.rb +++ b/lib/bert/encoder.rb @@ -17,11 +17,13 @@ module BERT def self.convert(item) case item when Hash - pairs = l[] + pairs = Erl::List[] item.each_pair { |k, v| pairs << [convert(k), convert(v)] } [:dict, pairs] - when Array + when Tuple item.map { |x| convert(x) } + when Array + Erl::List.new(item.map { |x| convert(x) }) when nil [:nil, :nil] when TrueClass, FalseClass diff --git a/test/bert_test.rb b/test/bert_test.rb index d2d4661..b6c5fc0 100644 --- a/test/bert_test.rb +++ b/test/bert_test.rb @@ -3,10 +3,10 @@ require 'test_helper' class BertTest < Test::Unit::TestCase context "BERT" do setup do - t = Time.at(1254976067) - @ruby = [:user, {:name => 'TPW'}, l[/cat/i, 9.9], nil, true, false, :true, :false] - @bert = "\203h\bd\000\004userh\002d\000\004dictl\000\000\000\001h\002d\000\004namem\000\000\000\003TPWjh\002h\003d\000\005regexm\000\000\000\003catm\000\000\000\001ic9.900000000000000e+00\000\000\000\000\000\000\000\000\000\000h\002d\000\003nild\000\003nilh\002d\000\004boold\000\004trueh\002d\000\004boold\000\005falsed\000\004trued\000\005false" - @ebin = "<<131,104,8,100,0,4,117,115,101,114,104,2,100,0,4,100,105,99,116,108,0,0,0,1,104,2,100,0,4,110,97,109,101,109,0,0,0,3,84,80,87,106,104,2,104,3,100,0,5,114,101,103,101,120,109,0,0,0,3,99,97,116,109,0,0,0,1,105,99,57,46,57,48,48,48,48,48,48,48,48,48,48,48,48,48,48,101,43,48,48,0,0,0,0,0,0,0,0,0,0,104,2,100,0,3,110,105,108,100,0,3,110,105,108,104,2,100,0,4,98,111,111,108,100,0,4,116,114,117,101,104,2,100,0,4,98,111,111,108,100,0,5,102,97,108,115,101,100,0,4,116,114,117,101,100,0,5,102,97,108,115,101>>" + time = Time.at(1254976067) + @ruby = t[:user, {:name => 'TPW'}, [/cat/i, 9.9], nil, true, false, :true, :false] + @bert = "\203h\bd\000\004userh\002d\000\004dictl\000\000\000\001h\002d\000\004namem\000\000\000\003TPWjl\000\000\000\002h\003d\000\005regexm\000\000\000\003catm\000\000\000\001ic9.900000000000000e+00\000\000\000\000\000\000\000\000\000\000jh\002d\000\003nild\000\003nilh\002d\000\004boold\000\004trueh\002d\000\004boold\000\005falsed\000\004trued\000\005false" + @ebin = "<<131,104,8,100,0,4,117,115,101,114,104,2,100,0,4,100,105,99,116,108,0,0,0,1,104,2,100,0,4,110,97,109,101,109,0,0,0,3,84,80,87,106,108,0,0,0,2,104,3,100,0,5,114,101,103,101,120,109,0,0,0,3,99,97,116,109,0,0,0,1,105,99,57,46,57,48,48,48,48,48,48,48,48,48,48,48,48,48,48,101,43,48,48,0,0,0,0,0,0,0,0,0,0,106,104,2,100,0,3,110,105,108,100,0,3,110,105,108,104,2,100,0,4,98,111,111,108,100,0,4,116,114,117,101,104,2,100,0,4,98,111,111,108,100,0,5,102,97,108,115,101,100,0,4,116,114,117,101,100,0,5,102,97,108,115,101>>" end should "encode" do @@ -20,5 +20,15 @@ class BertTest < Test::Unit::TestCase should "ebin" do assert_equal @ebin, BERT.ebin(@bert) end + + # should "let me inspect it" do + # puts + # p @ruby + # ruby2 = BERT.decode(@bert) + # p ruby2 + # bert2 = BERT.encode(ruby2) + # ruby3 = BERT.decode(bert2) + # p ruby3 + # end end end diff --git a/test/encoder_test.rb b/test/encoder_test.rb index 7b2c7d3..1c7be17 100644 --- a/test/encoder_test.rb +++ b/test/encoder_test.rb @@ -24,6 +24,29 @@ class EncoderTest < Test::Unit::TestCase assert_equal after, BERT::Encoder.convert(before) end + should "convert hash to tuple with array of tuples" do + arr = BERT::Encoder.convert({:foo => 'bar'}) + assert arr.is_a?(Array) + assert arr[1].is_a?(Erl::List) + assert arr[1][0].is_a?(Array) + end + + should "convert tuple to array" do + arr = BERT::Encoder.convert(t[:foo, 2]) + assert arr.is_a?(Array) + end + + should "convert array to erl list" do + list = BERT::Encoder.convert([1, 2]) + assert list.is_a?(Erl::List) + end + + should "convert an array in a tuple" do + arrtup = BERT::Encoder.convert(t[:foo, [1, 2]]) + assert arrtup.is_a?(Array) + assert arrtup[1].is_a?(Erl::List) + end + should "convert true" do before = true after = [:bool, :true] @@ -48,6 +71,14 @@ class EncoderTest < Test::Unit::TestCase assert_equal after, BERT::Encoder.convert(before) end + should "properly convert types" do + ruby = t[:user, {:name => 'TPW'}, [/cat/i, 9.9], nil, true, false, :true, :false] + cruby = BERT::Encoder.convert(ruby) + assert cruby.instance_of?(Array) + assert cruby[0].instance_of?(Symbol) + assert cruby[1].instance_of?(Array) + end + should "leave other stuff alone" do before = [1, 2.0, [:foo, 'bar']] assert_equal before, BERT::Encoder.convert(before) diff --git a/test/test_helper.rb b/test/test_helper.rb index d0ce6d5..596f3f1 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -8,3 +8,12 @@ require 'bert' class Test::Unit::TestCase end + +# So I can easily see which arrays are Erl::List +module Erl + class List + def inspect + "l#{super}" + end + end +end \ No newline at end of file