zweikopf 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,27 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ /target
19
+ /lib
20
+ /classes
21
+ /checkouts
22
+ pom.xml
23
+ *.jar
24
+ *.class
25
+ .lein-deps-sum
26
+ .lein-failures
27
+ .lein-plugins
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/.travis.yml ADDED
@@ -0,0 +1,6 @@
1
+ rvm:
2
+ - jruby
3
+ jdk:
4
+ - openjdk6
5
+ - openjdk7
6
+ script: "rake && lein2 test"
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in zweikopf.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Oleksandr Petrov
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,41 @@
1
+ # Zweihopf, a two-headed JVM friend of yours.
2
+
3
+ Zweikopf helps you to interoperate between Clojure and JRuby on JVM.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'zweikopf'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install zweikopf
18
+
19
+ # Performance
20
+
21
+ ## Conversion from Ruby hash to Clojure PersistentHash Map
22
+
23
+ Most of time 52% according to the rough estimate is spent while converting from ruby Symbol to clojure Keyword.
24
+
25
+ ## Usage
26
+
27
+ TODO: Write usage instructions here
28
+
29
+ ## Contributing
30
+
31
+ 1. Fork it
32
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
33
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
34
+ 4. Push to the branch (`git push origin my-new-feature`)
35
+ 5. Create new Pull Request
36
+
37
+ # Copyright
38
+
39
+ Copyright (C) 2011-2012 Alex Petrov, Maximilian Karasz, Daniel Steiner, Roman Flammer.
40
+
41
+ Distributed under the Eclipse Public License, the same as Clojure.
data/Rakefile ADDED
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+ require 'rspec/core/rake_task'
4
+
5
+ desc 'Default: run the specs and features.'
6
+ task :default => 'spec:all'
7
+
8
+ namespace :spec do
9
+ desc "Run all specs"
10
+ RSpec::Core::RakeTask.new('all') do |t|
11
+ t.pattern = 'spec/{**/*_spec.rb}'
12
+ end
13
+ end
Binary file
@@ -0,0 +1,40 @@
1
+ java_import "clojure.lang.PersistentHashMap"
2
+ java_import "clojure.lang.PersistentArrayMap"
3
+ java_import "clojure.lang.Keyword"
4
+ java_import "java.util.Map"
5
+
6
+ module Zweikopf
7
+ module Hash
8
+ def self.empty
9
+ PersistentHashMap::EMPTY
10
+ end
11
+
12
+ def self.create(hash)
13
+ ret = empty.as_transient
14
+ hash.each do |k, v|
15
+ if v.is_a?(::Hash)
16
+ ret = ret.assoc(Keyword.intern(k.to_s), self.create(v))
17
+ else
18
+ ret = ret.assoc(Keyword.intern(k.to_s), v)
19
+ end
20
+ end
21
+ ret.persistent
22
+ end
23
+
24
+ def self.from_clj(clj_hash)
25
+ {}.tap do |ruby_map|
26
+ clj_hash.each do |k, v|
27
+ if v.is_a?(PersistentHashMap) || v.is_a?(PersistentArrayMap)
28
+ ruby_map[clj_to_ruby_symbol(k)] = self.from_clj(v)
29
+ else
30
+ ruby_map[clj_to_ruby_symbol(k)] = v
31
+ end
32
+ end
33
+ end
34
+ end # self.from_clj
35
+
36
+ def self.clj_to_ruby_symbol(keyword)
37
+ keyword.to_s.gsub(/:/, "").to_sym
38
+ end # self.clj_to_ruby_symbol
39
+ end
40
+ end
@@ -0,0 +1,3 @@
1
+ module Zweikopf
2
+ VERSION = "0.0.1"
3
+ end
data/lib/zweikopf.rb ADDED
@@ -0,0 +1,6 @@
1
+ require "zweikopf/hash"
2
+ require "zweikopf/version"
3
+
4
+ module Zweikopf
5
+
6
+ end
data/project.clj ADDED
@@ -0,0 +1,5 @@
1
+ (defproject zweikopf "0.1.0-SNAPSHOT"
2
+ :description "jruby clojure interop"
3
+ :dependencies [[org.clojure/clojure "1.4.0"]
4
+ [org.jruby/jruby-complete "1.6.7.2"]]
5
+ :profiles {:dev {:dependencies []}})
@@ -0,0 +1 @@
1
+ [:a 1 :b 2 :c 3]
@@ -0,0 +1 @@
1
+ {:a 1 :b {:c 3 :d 4}}
@@ -0,0 +1 @@
1
+ {:a 1 :b 2}
@@ -0,0 +1 @@
1
+ {}
@@ -0,0 +1,29 @@
1
+ puts RUBY_PLATFORM
2
+
3
+ require 'java'
4
+
5
+
6
+ deps = File.join(File.dirname(__FILE__), "..", "deps")
7
+
8
+ # Dir["#{deps}/\*.jar"].each do |jar|
9
+ require "/Users/alexp/p/zweikopf/deps/clojure-1.4.0.jar" # jar
10
+ # end
11
+
12
+
13
+ java_import "clojure.lang.RT"
14
+
15
+ require 'zweikopf'
16
+
17
+ # Requires supporting ruby files with custom matchers and macros, etc,
18
+ # in spec/support/ and its subdirectories.
19
+ Dir["spec/support/**/*.rb"].each {|f| require f}
20
+
21
+ RSpec.configure do |config|
22
+ config.treat_symbols_as_metadata_keys_with_true_values = true
23
+ config.run_all_when_everything_filtered = true
24
+ config.filter_run :focus
25
+
26
+ config.order = 'random'
27
+
28
+ config.include Spec::Loader
29
+ end
@@ -0,0 +1,17 @@
1
+ java_import 'clojure.lang.Compiler'
2
+
3
+ module Spec
4
+ # Helper module for loading Clojure code
5
+ module Loader
6
+
7
+ # Loads fixture from the file located under spec/fixtures
8
+ #
9
+ # @param [String/Symbol] fixture_name: name of the fixture to load
10
+ # @return [undefined]
11
+ #
12
+ # @api public
13
+ def load_fixture(fixture_name)
14
+ Compiler.load_file("spec/fixtures/#{fixture_name}.clj")
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,102 @@
1
+ require 'spec_helper'
2
+
3
+ describe Zweikopf::Hash do
4
+ describe :empty do
5
+ let(:empty_hash) { load_fixture(:empty_hash) }
6
+
7
+ it "returns empty clojure hash" do
8
+ Zweikopf::Hash.empty.should eql empty_hash
9
+ end
10
+ end
11
+
12
+ describe :create do
13
+
14
+
15
+ context "when given a non-recursive hash structure" do
16
+
17
+ #
18
+ # Environment
19
+ #
20
+
21
+ let(:hash) { load_fixture(:clj_hash1) }
22
+
23
+ #
24
+ # Examples
25
+ #
26
+
27
+ it "creates a Clojure hash" do
28
+ Zweikopf::Hash.create({:a => 1, :b => 2}).should eql hash
29
+ end
30
+ end
31
+
32
+ context "when given a recursive hash structure" do
33
+
34
+ #
35
+ # Environment
36
+ #
37
+
38
+ let(:hash) { load_fixture(:clj_deep_hash1) }
39
+
40
+ #
41
+ # Examples
42
+ #
43
+
44
+ it "creates a Clojure hash" do
45
+ Zweikopf::Hash.create({:a => 1, :b => {:c => 3, :d =>4}}).should eql hash
46
+ end
47
+ end
48
+ end
49
+
50
+ describe :from_clj do
51
+ context "given a non-recursive clojure hash structure" do
52
+
53
+ #
54
+ # Environment
55
+ #
56
+
57
+ let(:clj_hash) { load_fixture(:clj_hash1) }
58
+
59
+ #
60
+ # Examples
61
+ #
62
+
63
+ it "creates a Ruby hash" do
64
+ Zweikopf::Hash.from_clj(clj_hash).should eql({:a => 1, :b => 2})
65
+ end
66
+ end
67
+
68
+ context "when given a recursive hash structure" do
69
+
70
+ #
71
+ # Environment
72
+ #
73
+
74
+ let(:clj_hash) { load_fixture(:clj_deep_hash1) }
75
+
76
+ #
77
+ # Examples
78
+ #
79
+
80
+ it "creates a Clojure hash" do
81
+ Zweikopf::Hash.from_clj(clj_hash).should eql({:a => 1, :b => {:c => 3, :d =>4}})
82
+ end
83
+ end
84
+
85
+ context "when given a clojure array" do
86
+
87
+ #
88
+ # Environment
89
+ #
90
+
91
+ let(:clj_array) { load_fixture(:clj_array1) }
92
+
93
+ #
94
+ # Examples
95
+ #
96
+
97
+ it "creates a Ruby array" do
98
+ #
99
+ end
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+
3
+ describe :performance do
4
+ it "this spec simply shows performance" do
5
+ time_before = Time.now.to_f
6
+ 100000.times do |i|
7
+ Zweikopf::Hash.create({:a => i, :b => i})
8
+ end
9
+ puts "Time elapsed: #{Time.now.to_f - time_before} seconds"
10
+ end
11
+ end
@@ -0,0 +1,33 @@
1
+ (ns zweikopf.core
2
+ (:require [clojure.reflect :as r])
3
+ (:import [org.jruby RubyObject RubyHash RubyBasicObject
4
+ RubySymbol RubyHash$RubyHashEntry RubyArray]
5
+ [org.jruby.javasupport JavaUtil]))
6
+
7
+ (defprotocol Clojurize
8
+ (clojurize [this]))
9
+
10
+ (extend-protocol Clojurize
11
+ java.lang.Object
12
+ (clojurize [this] this)
13
+ RubyObject
14
+ (clojurize [this] (JavaUtil/convertRubyToJava this))
15
+ RubySymbol
16
+ (clojurize [^RubySymbol this]
17
+ (clojure.lang.Keyword/intern (.toString this)))
18
+ RubyHash
19
+ (clojurize [^RubyHash this]
20
+ (loop [[^RubyHash$RubyHashEntry entry & entries] (seq (.directEntrySet this))
21
+ acc (transient {})]
22
+ (if entry
23
+ (recur entries
24
+ (assoc! acc (clojurize (.getKey entry))
25
+ (clojurize (.getValue entry))))
26
+ (persistent! acc))))
27
+ RubyArray
28
+ (clojurize [^RubyArray this]
29
+ (loop [[entry & entries] (seq this)
30
+ acc (transient [])]
31
+ (if entry
32
+ (recur entries (conj! acc (clojurize entry)))
33
+ (persistent! acc)))))
@@ -0,0 +1,23 @@
1
+ (ns zweikopf.core-test
2
+ (:import [org.jruby.embed ScriptingContainer])
3
+ (:use clojure.test
4
+ zweikopf.core))
5
+
6
+ (defn run-ruby-script [script]
7
+ (.runScriptlet (ScriptingContainer.) script))
8
+
9
+ (deftest hash-test
10
+ (testing "Empty hash"
11
+ (is (= {} (clojurize (run-ruby-script "{}")))))
12
+ (testing "Non-empty hash"
13
+ (is (= {:a 1 :b 2} (clojurize (run-ruby-script "{:a => 1, :b =>2 }")))))
14
+ (testing "Deep hash"
15
+ (is (= {:a 1 :b {:c 3 :d 4}} (clojurize (run-ruby-script "{:a => 1, :b => {:c => 3, :d =>4}}"))))))
16
+
17
+ (deftest array-test
18
+ (testing "Empty array"
19
+ (is (= [] (clojurize (run-ruby-script "[]")))))
20
+ (testing "Non-empty array"
21
+ (is (= [1 :a "b"]) (run-ruby-script "[1, :a, 'b']")))
22
+ (testing "Deep array"
23
+ (is (= [:a [:c :d] :e :f]) (run-ruby-script "[:a, [:c, :d], :e, :f]"))))
data/zweikopf.gemspec ADDED
@@ -0,0 +1,20 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/zweikopf/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Oleksandr Petrov"]
6
+ gem.email = ["oleksandr.petrov@gmail.com"]
7
+ gem.description = %q{Rubygem for jruby/clojure interop}
8
+ gem.summary = %q{It's good, try it out!}
9
+ gem.homepage = ""
10
+
11
+ gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
12
+ gem.files = `git ls-files`.split("\n")
13
+ gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
14
+ gem.name = "zweikopf"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = Zweikopf::VERSION
17
+
18
+ gem.add_development_dependency "rake"
19
+ gem.add_development_dependency "rspec"
20
+ end
metadata ADDED
@@ -0,0 +1,107 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: zweikopf
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.0.1
6
+ platform: ruby
7
+ authors:
8
+ - Oleksandr Petrov
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2012-07-17 00:00:00 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rake
17
+ prerelease: false
18
+ requirement: &id001 !ruby/object:Gem::Requirement
19
+ none: false
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ type: :development
25
+ version_requirements: *id001
26
+ - !ruby/object:Gem::Dependency
27
+ name: rspec
28
+ prerelease: false
29
+ requirement: &id002 !ruby/object:Gem::Requirement
30
+ none: false
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: "0"
35
+ type: :development
36
+ version_requirements: *id002
37
+ description: Rubygem for jruby/clojure interop
38
+ email:
39
+ - oleksandr.petrov@gmail.com
40
+ executables: []
41
+
42
+ extensions: []
43
+
44
+ extra_rdoc_files: []
45
+
46
+ files:
47
+ - .gitignore
48
+ - .rspec
49
+ - .travis.yml
50
+ - Gemfile
51
+ - LICENSE
52
+ - README.md
53
+ - Rakefile
54
+ - deps/clojure-1.4.0.jar
55
+ - lib/zweikopf.rb
56
+ - lib/zweikopf/hash.rb
57
+ - lib/zweikopf/version.rb
58
+ - project.clj
59
+ - spec/fixtures/clj_array1.clj
60
+ - spec/fixtures/clj_deep_hash1.clj
61
+ - spec/fixtures/clj_hash1.clj
62
+ - spec/fixtures/empty_hash.clj
63
+ - spec/spec_helper.rb
64
+ - spec/support/loader.rb
65
+ - spec/zweikopf/hash_spec.rb
66
+ - spec/zweikopf/performance_spec.rb
67
+ - src/zweikopf/core.clj
68
+ - test/zweikopf/core_test.clj
69
+ - zweikopf.gemspec
70
+ homepage: ""
71
+ licenses: []
72
+
73
+ post_install_message:
74
+ rdoc_options: []
75
+
76
+ require_paths:
77
+ - lib
78
+ required_ruby_version: !ruby/object:Gem::Requirement
79
+ none: false
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: "0"
84
+ required_rubygems_version: !ruby/object:Gem::Requirement
85
+ none: false
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: "0"
90
+ requirements: []
91
+
92
+ rubyforge_project:
93
+ rubygems_version: 1.8.24
94
+ signing_key:
95
+ specification_version: 3
96
+ summary: It's good, try it out!
97
+ test_files:
98
+ - spec/fixtures/clj_array1.clj
99
+ - spec/fixtures/clj_deep_hash1.clj
100
+ - spec/fixtures/clj_hash1.clj
101
+ - spec/fixtures/empty_hash.clj
102
+ - spec/spec_helper.rb
103
+ - spec/support/loader.rb
104
+ - spec/zweikopf/hash_spec.rb
105
+ - spec/zweikopf/performance_spec.rb
106
+ - test/zweikopf/core_test.clj
107
+ has_rdoc: