malachite 0.0.2 → 0.0.3
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.
- checksums.yaml +4 -4
- data/.gitignore +11 -0
- data/README.md +128 -0
- data/lib/malachite/exporter.go.tmpl +9 -0
- data/lib/malachite/main.go.tmpl +18 -0
- data/lib/malachite/tasks/malachite.rake +7 -0
- data/lib/malachite/version.rb +1 -1
- data/malachite.gemspec +21 -0
- metadata +8 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 15a0bee07fc12cc4a174e49741cbe6cbc5b247d5
|
4
|
+
data.tar.gz: 55611fa07c4f2465e419f188af6213b108036813
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9f99bffb3e811b277ca753d006678d1a84ecd00d9ab8e32b6a3aaa6cff736df55bb9de4c6eebd9b10bc170ca1c1acf9cb8f4d602c0f4e30e0c685c4c107104a5
|
7
|
+
data.tar.gz: 08e4d4d7aa44e7d3460c4707a74341066546ebafc33262450279f16c31707b21ce483e1622616a51f316324ce3df14d05febb94d91d325f23d29555345543b22
|
data/.gitignore
ADDED
data/README.md
ADDED
@@ -0,0 +1,128 @@
|
|
1
|
+
### Malachite
|
2
|
+
|
3
|
+
A RubyGem which enables calling Go code from Rails.
|
4
|
+
|
5
|
+
### Installation
|
6
|
+
|
7
|
+
Install [Go 1.5 or later](https://golang.org/doc/install) on relevant machines.
|
8
|
+
|
9
|
+
Add this to your Gemfile:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
gem 'malachite', github: 'zhubert/malachite'
|
13
|
+
```
|
14
|
+
|
15
|
+
Make a subdirectory of "app" called "go".
|
16
|
+
|
17
|
+
### Write Some Go Functions
|
18
|
+
|
19
|
+
Everything in "app/go" will get compiled into one namespace, so to get it to work with
|
20
|
+
Malachite, you need to:
|
21
|
+
|
22
|
+
* name the methods you want exported like: "HandleFoo"
|
23
|
+
* the Handle methods can only take one argument (use structs for more complexity)
|
24
|
+
|
25
|
+
For instance, if you wanted to upcase strings more quickly in your Rails app, you'd put the following in the file "app/go/upcase.go":
|
26
|
+
|
27
|
+
```go
|
28
|
+
package main
|
29
|
+
|
30
|
+
import (
|
31
|
+
"strings"
|
32
|
+
)
|
33
|
+
|
34
|
+
func HandleUpcase(things []string) (upperCased []string) {
|
35
|
+
for _, thing := range things {
|
36
|
+
upperCased = append(upperCased, strings.ToUpper(thing))
|
37
|
+
}
|
38
|
+
return
|
39
|
+
}
|
40
|
+
```
|
41
|
+
|
42
|
+
Then use your function from Rails:
|
43
|
+
|
44
|
+
```ruby
|
45
|
+
Malachite::Client.upcase(["foo","bar"])
|
46
|
+
=> ["FOO", "BAR"]
|
47
|
+
```
|
48
|
+
|
49
|
+
Or if you have more interesting data organize it with a struct:
|
50
|
+
|
51
|
+
```go
|
52
|
+
package main
|
53
|
+
|
54
|
+
import "strings"
|
55
|
+
|
56
|
+
type Person struct {
|
57
|
+
Name string `json:"name"`
|
58
|
+
Age string `json:"age"`
|
59
|
+
}
|
60
|
+
|
61
|
+
func HandleStructured(people []Person) (upperCasedPeople []Person) {
|
62
|
+
for _, person := range people {
|
63
|
+
upCase := Person{strings.ToUpper(person.Name), person.Age}
|
64
|
+
upperCasedPeople = append(upperCasedPeople, upCase)
|
65
|
+
}
|
66
|
+
return
|
67
|
+
}
|
68
|
+
```
|
69
|
+
|
70
|
+
```ruby
|
71
|
+
peeps = [{name: 'Peter', age: '27'},{name: 'Tim', age: '30'}]
|
72
|
+
Malachite::Client.structured(peeps)
|
73
|
+
=> [{"name"=>"PETER", "age"=>"27"}, {"name"=>"TIM", "age"=>"30"}]
|
74
|
+
```
|
75
|
+
|
76
|
+
Or even something totally arbitrary:
|
77
|
+
|
78
|
+
```go
|
79
|
+
package main
|
80
|
+
|
81
|
+
import "strings"
|
82
|
+
|
83
|
+
type Person struct {
|
84
|
+
Name string `json:"name"`
|
85
|
+
}
|
86
|
+
|
87
|
+
type Foo struct {
|
88
|
+
Friends []Person `json:"friends"`
|
89
|
+
Enemies []Person `json:"enemies"`
|
90
|
+
}
|
91
|
+
|
92
|
+
func HandleFrenemies(foo Foo) (frenemies []Person) {
|
93
|
+
for _, friend := range foo.Friends {
|
94
|
+
for _, enemy := range foo.Enemies {
|
95
|
+
if friend.Name == enemy.Name {
|
96
|
+
frenemies = append(frenemies, friend)
|
97
|
+
}
|
98
|
+
}
|
99
|
+
}
|
100
|
+
return
|
101
|
+
}
|
102
|
+
```
|
103
|
+
|
104
|
+
```ruby
|
105
|
+
friends = [{name: 'Peter'},{name: 'Tim'}]
|
106
|
+
enemies = [{name: 'Peter'},{name: 'Zeb'}]
|
107
|
+
Malachite::Client.frenemies({friends: friends, enemies: enemies})
|
108
|
+
=> [{"name"=>"Peter"}]
|
109
|
+
```
|
110
|
+
|
111
|
+
### How Does it Work?
|
112
|
+
|
113
|
+
Some code trickery, quite honestly.
|
114
|
+
|
115
|
+
* The first time the function is called, Malachite will build a shared library from all the Go code in your "app/go" folder
|
116
|
+
* It then uses Ruby's Fiddle to call the shared library
|
117
|
+
* Arguments are passed back and forth via JSON
|
118
|
+
|
119
|
+
Because of the JSON step, you'll only see real performance gains on computationally difficult tasks. Ruby's JSON conversion is a large tax.
|
120
|
+
|
121
|
+
### Ruby 2.2.4+
|
122
|
+
|
123
|
+
It's strongly recommended to use the [newest release of Ruby](https://www.ruby-lang.org/en/news/2015/12/16/unsafe-tainted-string-usage-in-fiddle-and-dl-cve-2015-7551/) as there was a security issue with older versions of Fiddle.
|
124
|
+
|
125
|
+
### TODO
|
126
|
+
|
127
|
+
* Error handling
|
128
|
+
* Benchmark performance...roughly
|
@@ -0,0 +1,18 @@
|
|
1
|
+
package main
|
2
|
+
import "encoding/json"
|
3
|
+
import "C"
|
4
|
+
|
5
|
+
func main() {}
|
6
|
+
|
7
|
+
func Unmarshal(data string, v interface{}) error {
|
8
|
+
err := json.Unmarshal([]byte(data), &v)
|
9
|
+
return err
|
10
|
+
}
|
11
|
+
|
12
|
+
func Marshal(v interface{}) string {
|
13
|
+
b, err := json.Marshal(v)
|
14
|
+
if err != nil {
|
15
|
+
return "{}"
|
16
|
+
}
|
17
|
+
return string(b)
|
18
|
+
}
|
data/lib/malachite/version.rb
CHANGED
data/malachite.gemspec
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require File.expand_path('../lib/malachite/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |spec|
|
5
|
+
spec.authors = ['Zack Hubert']
|
6
|
+
spec.email = ['zhubert@gmail.com']
|
7
|
+
spec.summary = 'A RubyGem which enables calling Go code from Ruby'
|
8
|
+
spec.description = 'A RubyGem which enables calling Go code from Ruby.'
|
9
|
+
spec.homepage = 'http://www.zhubert.com'
|
10
|
+
spec.license = 'MIT'
|
11
|
+
|
12
|
+
spec.files = `git ls-files`.split("\n")
|
13
|
+
spec.name = 'malachite'
|
14
|
+
spec.require_paths = ['lib']
|
15
|
+
spec.version = Malachite::VERSION
|
16
|
+
|
17
|
+
|
18
|
+
spec.add_dependency 'json', '~> 1.0'
|
19
|
+
spec.add_development_dependency 'bundler', '~> 1.9'
|
20
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
21
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: malachite
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Zack Hubert
|
@@ -59,15 +59,21 @@ executables: []
|
|
59
59
|
extensions: []
|
60
60
|
extra_rdoc_files: []
|
61
61
|
files:
|
62
|
+
- ".gitignore"
|
62
63
|
- Gemfile
|
64
|
+
- README.md
|
63
65
|
- Rakefile
|
64
66
|
- lib/malachite.rb
|
65
67
|
- lib/malachite/client.rb
|
66
68
|
- lib/malachite/compiler.rb
|
67
69
|
- lib/malachite/errors.rb
|
70
|
+
- lib/malachite/exporter.go.tmpl
|
71
|
+
- lib/malachite/main.go.tmpl
|
68
72
|
- lib/malachite/railtie.rb
|
69
73
|
- lib/malachite/tasks.rb
|
74
|
+
- lib/malachite/tasks/malachite.rake
|
70
75
|
- lib/malachite/version.rb
|
76
|
+
- malachite.gemspec
|
71
77
|
homepage: http://www.zhubert.com
|
72
78
|
licenses:
|
73
79
|
- MIT
|
@@ -91,5 +97,5 @@ rubyforge_project:
|
|
91
97
|
rubygems_version: 2.4.5.1
|
92
98
|
signing_key:
|
93
99
|
specification_version: 4
|
94
|
-
summary: A RubyGem which enables calling Go code from Ruby
|
100
|
+
summary: A RubyGem which enables calling Go code from Ruby
|
95
101
|
test_files: []
|