node_module 0.1.3 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
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