node_module 0.1.3 → 0.1.4

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/README.md CHANGED
@@ -4,33 +4,23 @@
4
4
  >
5
5
  > &mdash; <cite>https://twitter.com/shit_hn_says/status/234856345579446272</cite>
6
6
 
7
- Ruby is a pretty high level language, so isn't perfectly suited to
8
- things such as:
7
+ Dropping down to node.js has a number of problems:
9
8
 
10
- 1. Systems programming
11
- 2. Being web-scale
9
+ 1. You introduce a new, fairly large dependency to your codebase
10
+ 2. You have to maintain certain stuff in a different language
11
+ 3. You open yourself up to various debates about callbacks and promises
12
12
 
13
- It's also difficult to represent basic concepts in Ruby, as the sheer
14
- amount of dynamism and expressivity baked into the language compels
15
- the programmer to only think of code in terms of objects and
16
- orientation, and Dijkstra. This is way too high level.
13
+ On the other hand, it has a couple of major advantages over every other language ever:
17
14
 
18
- Thankfully, there is a burgeoning language on the scene that empowers
19
- the programmer to really think about the nuts and bolts of their
20
- implementation. Your code no longer explains to you what you want to
21
- happen, but how it should do it.
15
+ 1. It's web-scale
16
+ 2. It's *web-scale*!
22
17
 
23
- Naturally, issuing commands to a computer -- typically in the form of
24
- an assembly language, compiled C code, or JavaScript -- allows the
25
- program to scale effortlessly under extreme loads, and allows you to reason
26
- about what exactly your hardware is doing.
18
+ Wouldn't it be nice if you could drop down to Node... *implicitly*?
19
+ You wouldn't need to significantly change anything to fine-tune
20
+ portions of your app, right down to the individual method level.
27
21
 
28
- To that end, this library lets you drop down to JavaScript at the method level,
29
- so parts of your class can be executed more efficiently. This makes Ruby *perfectly*
30
- suited to things such as:
31
-
32
- 1. Systems programming
33
- 2. Being web-scale
22
+ Enter `node_module`, which does just that. All you need to do is add the gem, and
23
+ tell it which methods you want to run as javascript instead of Ruby.
34
24
 
35
25
  ## How to install
36
26
 
@@ -63,6 +53,14 @@ class AbstractConcepts
63
53
  (constants - [self.class]).map(&:remove_const)
64
54
  end
65
55
 
56
+ def meaning_of_life
57
+ 42
58
+ end
59
+
60
+ # run a specific method as javascript
61
+ node_module :meaning_of_life
62
+
63
+ # run everything after this point as javascript
66
64
  node_module
67
65
 
68
66
  def pythagorean_triplet?(a, b, c)
@@ -71,21 +69,23 @@ class AbstractConcepts
71
69
  end
72
70
  ```
73
71
 
74
- Any method you define after `node_module` will be converted to JavaScript before being
75
- executed.
72
+ `node_module` behaves like the `public`, `private`, and `protected`
73
+ methods Ruby gives you. You can pass in specific methods as symbols,
74
+ or call it without any arguments to change every subsequently
75
+ defined method.
76
76
 
77
77
  This is a ridiculous proof of concept, so there are a few issues...
78
78
 
79
79
  ## Current limitations
80
80
 
81
- - Things might break if your methods aren't fully self-contained. This
82
- is because they're currently compiled outside of the scope of the
83
- class they were defined in. (Although there's nothing preventing an entire class
84
- being parsed as javascript in future).
81
+ - Sharing state between methods or across a class is unpredictable,
82
+ and will probably cause bad things to happen.
85
83
 
86
- - It doesn't actually use Node yet
84
+ - It's destructive, so you'll lose the body of the original
85
+ method. This means you can't yet switch a method between its Ruby
86
+ and Javascript versions.
87
87
 
88
- - It buggers up IRB
88
+ - It doesn't actually use Node yet
89
89
 
90
90
  - It probably can't handle anything too clever.
91
91
 
@@ -0,0 +1,23 @@
1
+ require 'v8'
2
+ require 'json'
3
+ require 'opal'
4
+
5
+ class NodeModule::OpalJsContext < V8::Context
6
+
7
+ def initialize
8
+ super do |ctx|
9
+ ctx.eval Opal::Builder.build('opal')
10
+ end
11
+ end
12
+
13
+ def compile(code)
14
+ eval Opal.parse(code)
15
+ end
16
+
17
+ def run(name, args=[])
18
+ eval <<-JS
19
+ Opal.Object['$#{name}'].apply(Opal.Object, #{args.to_json})
20
+ JS
21
+ end
22
+
23
+ end
@@ -1,3 +1,3 @@
1
1
  module NodeModule
2
- VERSION = "0.1.3"
2
+ VERSION = "0.1.4"
3
3
  end
data/lib/node_module.rb CHANGED
@@ -1,28 +1,17 @@
1
1
  require 'node_module/version'
2
2
  require 'live_ast/to_ruby'
3
3
  require 'live_ast/irb_spy' if defined?(IRB)
4
- require 'opal'
5
- require 'json'
6
- require 'v8'
7
4
 
8
5
  module NodeModule
9
6
 
7
+ autoload :OpalJsContext, 'node_module/opal_js_context'
8
+
10
9
  def self.included(base)
11
10
  base.extend ClassMethods
12
11
  end
13
12
 
14
- def self.js_context
15
- @ctx ||= V8::Context.new do |ctx|
16
- ctx.eval Opal::Builder.build('opal')
17
- end
18
- end
19
-
20
- def self.convert_method_to_javascript(fn)
21
- NodeModule.js_context.eval Opal.parse(fn)
22
- end
23
-
24
- def self.call_javascript_function(name, args = [])
25
- NodeModule.js_context.eval "Opal.Object['$#{name}'].apply(this, #{args.to_json})"
13
+ def self.opal_js_context
14
+ @ctx ||= OpalJsContext.new
26
15
  end
27
16
 
28
17
  module ClassMethods
@@ -40,10 +29,11 @@ module NodeModule
40
29
  def self.execute_methods_as_javascript!(methods, receiver)
41
30
  methods.each do |name|
42
31
  meth = receiver.instance_method(name).to_ruby
43
- NodeModule.convert_method_to_javascript(meth)
32
+
33
+ NodeModule.opal_js_context.compile(meth)
44
34
 
45
35
  receiver.send :define_method, name do |*args|
46
- NodeModule.call_javascript_function(__method__, args)
36
+ NodeModule.opal_js_context.run(__method__, args)
47
37
  end
48
38
  end
49
39
  end
data/node_module.gemspec CHANGED
@@ -23,4 +23,5 @@ Gem::Specification.new do |spec|
23
23
  spec.add_dependency "opal"
24
24
  spec.add_development_dependency "bundler", "~> 1.3"
25
25
  spec.add_development_dependency "rake"
26
+ spec.add_development_dependency "minitest"
26
27
  end
@@ -0,0 +1,44 @@
1
+ require 'spec_helper'
2
+
3
+ describe NodeModule::OpalJsContext do
4
+
5
+ subject { NodeModule::OpalJsContext.new }
6
+
7
+ let(:predicate_method) { "def equal?(a, b); a == b; end;" }
8
+ let(:bang_method) { "def boom!; 'BOOM!'; end;" }
9
+ let(:mixed_method) { "def boom?(a, b); boom! if a == b; end;" }
10
+
11
+ describe "#load" do
12
+ it "successfully turns Ruby into Opal-style Javascript" do
13
+ js = subject.compile(predicate_method)
14
+ js.to_s.must_match /function \(a, b\) \{\s+ return a\['\$=='\]\(b\);\s+\}/
15
+ end
16
+ end
17
+
18
+ describe "#run" do
19
+ before do
20
+ subject.compile(predicate_method)
21
+ subject.compile(bang_method)
22
+ subject.compile(mixed_method)
23
+ end
24
+
25
+ it "handles Ruby style predicate methods" do
26
+ result = subject.run('equal?', [1, 1])
27
+ result.must_equal true
28
+
29
+ result = subject.run('equal?', [1, 2])
30
+ result.must_equal false
31
+ end
32
+
33
+ it "handles Ruby style bang methods" do
34
+ result = subject.run('boom!')
35
+ result.must_equal 'BOOM!'
36
+ end
37
+
38
+ it "can refer to previously defined methods from within a method" do
39
+ result = subject.run('boom?', [1, 1])
40
+ result.must_equal 'BOOM!'
41
+ end
42
+ end
43
+
44
+ end
@@ -1,8 +1,8 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe NodeModule do
3
+ describe NodeModule, "integration into other classes" do
4
4
 
5
- class TestClass
5
+ class ExampleClass
6
6
  include NodeModule
7
7
 
8
8
  node_module
@@ -10,48 +10,31 @@ describe NodeModule do
10
10
  def hello_you(*names)
11
11
  "hello #{names.join(', ')}"
12
12
  end
13
- end
14
-
15
-
16
-
17
- describe "integration" do
18
- let(:test_class) { TestClass.new }
19
13
 
20
- it "says 'hello' to all the people" do
21
- test_class.hello_you("Sarah", "Jess").must_equal "hello Sarah, Jess"
14
+ def goodbye_you(*names)
15
+ "goodbye #{names.join(', ')}"
22
16
  end
23
- end
24
-
25
- describe "#convert_method_to_javascript" do
26
- let(:test_method) { "def equal?(a, b); a == b; end;" }
27
17
 
28
- it "successfully turns Ruby into Opal-style Javascript" do
29
- js = NodeModule.convert_method_to_javascript(test_method)
30
- js.to_s.must_match /function \(a, b\) \{\s+ return a\['\$=='\]\(b\);\s+\}/
18
+ def equal?(a, b)
19
+ a == b
31
20
  end
32
- end
33
21
 
34
- describe "#call_javascript_function" do
35
- let(:predicate_method) { "def equal?(a, b); a == b; end;" }
36
- let(:bang_method) { "def boom!; 'BOOM!'; end;" }
37
-
38
- before do
39
- NodeModule.convert_method_to_javascript(predicate_method)
40
- NodeModule.convert_method_to_javascript(bang_method)
22
+ def not_equal?(a, b)
23
+ ! equal?(a, b)
41
24
  end
25
+ end
42
26
 
43
- it "handles Ruby style predicate methods" do
44
- result = NodeModule.call_javascript_function('equal?', [1, 1])
45
- result.must_equal true
27
+ let(:example_class) { ExampleClass.new }
46
28
 
47
- result = NodeModule.call_javascript_function('equal?', [1, 2])
48
- result.must_equal false
49
- end
29
+ it "says 'hello' to all the people" do
30
+ example_class.hello_you("Sarah", "Jess").must_equal "hello Sarah, Jess"
31
+ end
50
32
 
51
- it "handles Ruby style bang methods" do
52
- result = NodeModule.call_javascript_function('boom!')
53
- result.must_equal 'BOOM!'
54
- end
33
+ it "says 'goodbye' to all the people" do
34
+ example_class.goodbye_you("Tom", "Hayley").must_equal "goodbye Tom, Hayley"
55
35
  end
56
36
 
37
+ it "returns true if 1 is not equal to 2" do
38
+ example_class.not_equal?(1, 2).must_equal true
39
+ end
57
40
  end
data/spec/spec_helper.rb CHANGED
@@ -1,6 +1,5 @@
1
+ require 'minitest/autorun'
1
2
  require 'minitest/spec'
2
- require 'minitest/mock'
3
3
  require 'minitest/pride'
4
- require 'minitest/autorun'
5
4
 
6
5
  require File.expand_path('../../lib/node_module.rb', __FILE__)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: node_module
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.1.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-08-18 00:00:00.000000000 Z
12
+ date: 2013-08-19 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: live_ast
@@ -91,6 +91,22 @@ dependencies:
91
91
  - - ! '>='
92
92
  - !ruby/object:Gem::Version
93
93
  version: '0'
94
+ - !ruby/object:Gem::Dependency
95
+ name: minitest
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
94
110
  description: Evaluate methods in Ruby as Javascript instead
95
111
  email:
96
112
  - lee@new-bamboo.co.uk
@@ -105,8 +121,10 @@ files:
105
121
  - README.md
106
122
  - Rakefile
107
123
  - lib/node_module.rb
124
+ - lib/node_module/opal_js_context.rb
108
125
  - lib/node_module/version.rb
109
126
  - node_module.gemspec
127
+ - spec/lib/node_module/opal_js_context_spec.rb
110
128
  - spec/lib/node_module_spec.rb
111
129
  - spec/spec_helper.rb
112
130
  homepage: http://github.com/leemachin/node_module
@@ -124,7 +142,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
124
142
  version: '0'
125
143
  segments:
126
144
  - 0
127
- hash: -2154653241690516822
145
+ hash: -2723743550254407902
128
146
  required_rubygems_version: !ruby/object:Gem::Requirement
129
147
  none: false
130
148
  requirements:
@@ -133,7 +151,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
133
151
  version: '0'
134
152
  segments:
135
153
  - 0
136
- hash: -2154653241690516822
154
+ hash: -2723743550254407902
137
155
  requirements: []
138
156
  rubyforge_project:
139
157
  rubygems_version: 1.8.23
@@ -141,5 +159,6 @@ signing_key:
141
159
  specification_version: 3
142
160
  summary: Get really close to the metal in Ruby
143
161
  test_files:
162
+ - spec/lib/node_module/opal_js_context_spec.rb
144
163
  - spec/lib/node_module_spec.rb
145
164
  - spec/spec_helper.rb