zweikopf 0.0.1

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.
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: