Permalink
Browse files

added to_ruby method to convert Clojure objects to equivalent, yucky,…

… mutable Ruby objects :)
  • Loading branch information...
1 parent f6fcf84 commit d02cc274137958dfe4a360ff64f9a5d32cb52c75 @daveray committed Oct 18, 2011
Showing with 119 additions and 1 deletion.
  1. +3 −1 README.md
  2. +60 −0 lib/familiar.rb
  3. +56 −0 test/test_familiar.rb
View
@@ -60,7 +60,7 @@ So, to inspect the value of a *finite* lazy sequence in IRB, use the `inspect!`
=> "(0.5428756368923673 0.598041516780956)"
# Type Conversions
-The `to_clojure` method is added to Ruby datastructures so you can easily convert from Ruby literals to Clojure persistent structures. For example, this Ruby code:
+The `to_clojure` method is added to Ruby data structures so you can easily convert from Ruby literals to Clojure persistent structures. For example, this Ruby code:
[[1, 2, 3], {"hi" => "bye", :foo => [4, 5, 6]}].to_clojure
@@ -71,6 +71,8 @@ is equivalent to this Clojure code:
Note that Ruby Symbols are converted to Clojure keywords.
+Similarly, Clojure data structures can be converted to equivalent, native, data structures using the `to_ruby` method.
+
# Functions
Make a function from a proc or lambda:
View
@@ -328,6 +328,10 @@ def self.to_clojure(v)
v.respond_to?(:to_clojure) ? v.to_clojure : v
end
+ def self.to_ruby(v)
+ v.respond_to?(:to_ruby) ? v.to_ruby : v
+ end
+
class ::Array
def to_clojure
f = Familiar
@@ -358,6 +362,62 @@ def to_clojure
end
end
+ class Java::ClojureLang::Keyword
+ def to_ruby
+ name.intern
+ end
+ end
+
+ module ListToRuby
+ def to_ruby
+ r = []
+ each do |v|
+ r << Familiar.to_ruby(v)
+ end
+ r
+ end
+ end
+
+ class Java::ClojureLang::PersistentVector
+ include ListToRuby
+ end
+
+ class Java::ClojureLang::PersistentList
+ include ListToRuby
+ end
+
+ class Java::ClojureLang::LazySeq
+ include ListToRuby
+ end
+
+ module MapToRuby
+ def to_ruby
+ r = {}
+ each do |k,v|
+ r[Familiar.to_ruby(k)] = Familiar.to_ruby(v)
+ end
+ r
+ end
+ end
+
+ class Java::ClojureLang::PersistentArrayMap
+ include MapToRuby
+ end
+
+ class Java::ClojureLang::PersistentHashMap
+ include MapToRuby
+ end
+
+ class Java::ClojureLang::PersistentHashSet
+ def to_ruby
+ r = Set.new
+ each do |v|
+ r.add(Familiar.to_ruby(v))
+ end
+ r
+ end
+ end
+
#############################################################################
# REPL
if $0 != __FILE__
View
@@ -211,5 +211,61 @@ def test_recursively_converts_ruby_object_to_clojure
f.keyword("foo"), f.vector(4, 5, 6))).equals(clojure)
end
+ def test_can_convert_a_clojure_keyword_to_ruby_symbol
+ rb = Familiar.keyword("hello").to_ruby
+ assert rb.class == Symbol
+ assert_equal :hello, rb
+ end
+
+ def test_can_convert_a_clojure_vector_to_ruby_array
+ rb = Familiar.vector(5, 6, 7).to_ruby
+ assert rb.class == Array
+ assert_equal [5, 6, 7], rb
+ end
+
+ def test_can_convert_a_clojure_list_to_ruby_array
+ rb = Familiar.list(5, 6, 7).to_ruby
+ assert rb.class == Array
+ assert_equal [5, 6, 7], rb
+ end
+
+ def test_can_convert_a_clojure_seq_to_ruby_array
+ rb = Familiar.range(5).to_ruby
+ assert rb.class == Array
+ assert_equal [0, 1, 2, 3, 4], rb
+ end
+
+ def test_can_convert_a_clojure_array_map_to_ruby_hash
+ rb = Familiar.array_map("hi", "bye", "yum", "bar").to_ruby
+ assert rb.class == Hash
+ assert_equal({"hi" => "bye", "yum" => "bar" }, rb)
+ end
+
+ def test_can_convert_a_clojure_hash_map_to_ruby_hash
+ rb = Familiar.hash_map("hi", "bye", "yum", "bar").to_ruby
+ assert rb.class == Hash
+ assert_equal({"hi" => "bye", "yum" => "bar" }, rb)
+
+ end
+
+ def test_can_convert_a_clojure_hash_set_to_ruby_set
+ rb = Familiar.hash_set("a", 4, 1).to_ruby
+ assert rb.class == Set
+ assert_equal Set.new(["a", 1, 4]), rb
+ end
+
+ def test_can_convert_nested_clojure_objects_to_ruby
+ rb = Familiar.with do
+ hash_map(keyword("foo"), "bar",
+ "yum", vector(:yum, 2, 3),
+ 99, hash_set("a", "b", keyword("c")))
+ end.to_ruby
+
+ assert rb.class == Hash
+ assert_equal({:foo => "bar",
+ "yum" => [:yum, 2, 3],
+ 99 => Set.new(["a", "b", :c])}, rb)
+ end
+
end

0 comments on commit d02cc27

Please sign in to comment.