opal 0.3.20 → 0.3.21
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -7
- data/.rspec +2 -0
- data/.travis.yml +11 -0
- data/Gemfile +8 -2
- data/LICENSE +2 -3
- data/README.md +106 -239
- data/Rakefile +58 -16
- data/bin/opal +1 -0
- data/core/array.rb +180 -160
- data/core/basic_object.rb +8 -4
- data/core/boolean.rb +6 -6
- data/core/class.rb +9 -15
- data/core/dir.rb +89 -0
- data/core/enumerable.rb +83 -86
- data/core/error.rb +9 -4
- data/core/file.rb +85 -0
- data/core/hash.rb +67 -67
- data/core/kernel.rb +38 -42
- data/core/module.rb +57 -54
- data/core/numeric.rb +41 -41
- data/core/proc.rb +1 -5
- data/core/range.rb +11 -11
- data/core/regexp.rb +27 -22
- data/core/runtime.js +152 -221
- data/core/string.rb +86 -73
- data/core/time.rb +22 -18
- data/docs/post.html +9 -0
- data/docs/pre.html +32 -0
- data/lib/opal.rb +43 -3
- data/lib/opal/builder.rb +9 -26
- data/lib/opal/grammar.rb +1 -1
- data/lib/opal/grammar.y +1 -1
- data/lib/opal/lexer.rb +21 -15
- data/lib/opal/parser.rb +100 -111
- data/lib/opal/rake_task.rb +66 -0
- data/lib/opal/scope.rb +13 -5
- data/lib/opal/version.rb +1 -1
- data/opal.gemspec +2 -0
- data/spec/browser_spec.rb +28 -0
- data/spec/builder/lib_name_for_spec.rb +1 -6
- data/spec/grammar/alias_spec.rb +1 -1
- data/spec/grammar/and_spec.rb +1 -1
- data/spec/grammar/array_spec.rb +1 -1
- data/spec/grammar/attrasgn_spec.rb +1 -1
- data/spec/grammar/begin_spec.rb +1 -1
- data/spec/grammar/block_spec.rb +1 -1
- data/spec/grammar/break_spec.rb +1 -1
- data/spec/grammar/call_spec.rb +1 -1
- data/spec/grammar/class_spec.rb +1 -1
- data/spec/grammar/const_spec.rb +1 -1
- data/spec/grammar/cvar_spec.rb +1 -1
- data/spec/grammar/def_spec.rb +1 -1
- data/spec/grammar/false_spec.rb +1 -1
- data/spec/grammar/file_spec.rb +1 -1
- data/spec/grammar/gvar_spec.rb +1 -1
- data/spec/grammar/hash_spec.rb +1 -1
- data/spec/grammar/iasgn_spec.rb +1 -1
- data/spec/grammar/if_spec.rb +1 -1
- data/spec/grammar/iter_spec.rb +1 -1
- data/spec/grammar/ivar_spec.rb +1 -1
- data/spec/grammar/lambda_spec.rb +1 -1
- data/spec/grammar/lasgn_spec.rb +1 -1
- data/spec/grammar/line_spec.rb +1 -1
- data/spec/grammar/lvar_spec.rb +1 -1
- data/spec/grammar/masgn_spec.rb +1 -1
- data/spec/grammar/module_spec.rb +1 -1
- data/spec/grammar/nil_spec.rb +1 -1
- data/spec/grammar/not_spec.rb +1 -1
- data/spec/grammar/op_asgn1_spec.rb +1 -1
- data/spec/grammar/op_asgn2_spec.rb +1 -1
- data/spec/grammar/or_spec.rb +1 -1
- data/spec/grammar/return_spec.rb +1 -1
- data/spec/grammar/sclass_spec.rb +1 -1
- data/spec/grammar/self_spec.rb +1 -1
- data/spec/grammar/str_spec.rb +1 -1
- data/spec/grammar/super_spec.rb +1 -1
- data/spec/grammar/true_spec.rb +1 -1
- data/spec/grammar/undef_spec.rb +1 -1
- data/spec/grammar/unless_spec.rb +1 -1
- data/spec/grammar/while_spec.rb +1 -1
- data/spec/grammar/xstr_spec.rb +1 -1
- data/spec/grammar/yield_spec.rb +1 -1
- data/spec/spec_helper.rb +6 -1
- data/test/core/array/minus_spec.rb +13 -0
- data/test/core/enumerable/drop_while_spec.rb +0 -5
- data/test/core/range/case_compare_spec.rb +0 -1
- data/test/index.html +1 -1
- data/test/index.min.html +12 -0
- data/test/language/alias_spec.rb +0 -4
- data/test/language/fixtures/next.rb +62 -0
- data/test/language/metaclass_spec.rb +4 -4
- data/test/language/next_spec.rb +0 -63
- data/test/language/send_spec.rb +0 -5
- data/test/language/singleton_class_spec.rb +4 -0
- data/test/opal/array/subclassing_spec.rb +1 -1
- data/test/opal/class/bridge_class_spec.rb +2 -2
- data/test/opal/runtime/class_hierarchy_spec.rb +1 -2
- data/test/opal/runtime/method_missing_spec.rb +17 -0
- data/test/spec_helper.rb +4 -1
- metadata +32 -28
- data/docs/CNAME +0 -1
- data/docs/Rakefile +0 -55
- data/docs/css/styles.css +0 -50
- data/docs/css/syntax.css +0 -63
- data/docs/layout/post.html +0 -3
- data/docs/layout/pre.html +0 -11
- data/examples/dependencies/.gitignore +0 -1
- data/examples/dependencies/Gemfile +0 -6
- data/examples/dependencies/README.md +0 -41
- data/examples/dependencies/Rakefile +0 -10
- data/examples/dependencies/app.rb +0 -19
- data/examples/dependencies/build/.gitkeep +0 -0
- data/examples/dependencies/index.html +0 -13
- data/examples/hello_world/.gitignore +0 -1
- data/examples/hello_world/Gemfile +0 -3
- data/examples/hello_world/README.md +0 -27
- data/examples/hello_world/Rakefile +0 -23
- data/examples/hello_world/app.rb +0 -7
- data/examples/hello_world/index.html +0 -12
- data/lib/opal/builder_task.rb +0 -91
- data/spec/builder/build_order_spec.rb +0 -20
- data/test/opal/runtime/_methods_spec.rb +0 -48
data/.gitignore
CHANGED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
CHANGED
@@ -6,6 +6,12 @@ gem "rake"
|
|
6
6
|
gem "racc"
|
7
7
|
|
8
8
|
group :browser do
|
9
|
-
gem
|
10
|
-
gem 'opal-dom'
|
9
|
+
gem 'opal-spec', :git => 'git://github.com/adambeynon/opal-spec.git'
|
10
|
+
gem 'opal-dom', :git => 'git://github.com/adambeynon/opal-dom.git'
|
11
|
+
gem 'capybara'
|
12
|
+
end
|
13
|
+
|
14
|
+
group :docs do
|
15
|
+
gem "redcarpet"
|
16
|
+
gem "albino"
|
11
17
|
end
|
data/LICENSE
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
Copyright (C)
|
1
|
+
Copyright (C) 2012 by Adam Beynon
|
2
2
|
|
3
3
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
4
|
of this software and associated documentation files (the "Software"), to deal
|
@@ -16,5 +16,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
16
16
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
17
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
18
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
-
THE SOFTWARE.
|
20
|
-
|
19
|
+
THE SOFTWARE.
|
data/README.md
CHANGED
@@ -19,15 +19,11 @@ is a Freenode IRC channel at `#opal`.
|
|
19
19
|
The Opal runtime and corelib are distributed here, and are required to
|
20
20
|
run any code generated by opal.
|
21
21
|
|
22
|
-
[Opal version 0.3.
|
22
|
+
[Opal version 0.3.21](http://opalrb.org/opal.js) _(13.1kb Minified And Gzipped)_
|
23
23
|
|
24
24
|
## Installation
|
25
25
|
|
26
|
-
Opal
|
27
|
-
|
28
|
-
gem install opal
|
29
|
-
|
30
|
-
Or add to your Gemfile:
|
26
|
+
Opal should be added to your Gemfile:
|
31
27
|
|
32
28
|
```ruby
|
33
29
|
gem "opal"
|
@@ -35,139 +31,150 @@ gem "opal"
|
|
35
31
|
|
36
32
|
## Usage
|
37
33
|
|
38
|
-
|
39
|
-
|
34
|
+
The easiest way to use opal is to create a rake task using the
|
35
|
+
`RakeTask` helper class. Assuming you have a single ruby file in
|
36
|
+
your Opal app called `app.rb`:
|
40
37
|
|
41
38
|
```ruby
|
42
|
-
|
43
|
-
|
44
|
-
Opal.parse("puts 'hello world'")
|
39
|
+
# app.rb
|
40
|
+
puts "Hello world"
|
45
41
|
```
|
46
42
|
|
47
|
-
|
43
|
+
Then create a rake task similar to:
|
48
44
|
|
49
|
-
```
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
45
|
+
```ruby
|
46
|
+
# Rakefile
|
47
|
+
require 'opal/rake_task'
|
48
|
+
|
49
|
+
Opal::RakeTask.new do |t|
|
50
|
+
t.files = ['app.rb']
|
51
|
+
end
|
54
52
|
```
|
55
53
|
|
56
|
-
|
57
|
-
global javascript variable that holds all the ruby classes and methods.
|
58
|
-
`Opal.top` points to the top object in opal, so any file will have this
|
59
|
-
object as its top level `self` variable.
|
54
|
+
### Building the app
|
60
55
|
|
61
|
-
|
56
|
+
Building the app is as simple as running:
|
62
57
|
|
63
|
-
|
64
|
-
|
58
|
+
```
|
59
|
+
rake opal:build
|
60
|
+
```
|
61
|
+
|
62
|
+
This will build all your listed files into `build/app_name.js`. The
|
63
|
+
output name is based on the directory name. This can be overriden by
|
64
|
+
setting the `.name` property in the task:
|
65
65
|
|
66
66
|
```ruby
|
67
|
-
|
67
|
+
Opal::RakeTask.new do |t|
|
68
|
+
t.files = ['app.rb']
|
69
|
+
t.name = 'my_awesome_app'
|
70
|
+
end
|
71
|
+
```
|
68
72
|
|
69
|
-
|
73
|
+
### Building opal runtime
|
70
74
|
|
71
|
-
|
72
|
-
|
73
|
-
src = File.read 'app.rb'
|
74
|
-
js = Opal.parse src
|
75
|
+
To run the app in the browser, the opal runtime is required. This can
|
76
|
+
be built using:
|
75
77
|
|
76
|
-
|
77
|
-
|
78
|
-
|
78
|
+
```
|
79
|
+
rake opal:dependencies
|
80
|
+
```
|
81
|
+
|
82
|
+
Which will build `opal.js` into `./build`.
|
83
|
+
|
84
|
+
The output directory can also be overriden inside the rake task:
|
85
|
+
|
86
|
+
```ruby
|
87
|
+
Opal::RakeTask.new do |t|
|
88
|
+
t.files = ['app.rb']
|
89
|
+
t.build_dir = 'out_dir'
|
79
90
|
end
|
80
91
|
```
|
81
92
|
|
82
|
-
|
83
|
-
write it out to a file ready to load in a web browser.
|
93
|
+
The output directory will be created if it doesn't exist.
|
84
94
|
|
85
|
-
###
|
95
|
+
### Running the app
|
86
96
|
|
87
|
-
The
|
88
|
-
|
97
|
+
The two compiled files need to be added to a html page so that they
|
98
|
+
can run in the browser:
|
89
99
|
|
90
100
|
```html
|
91
101
|
<!doctype html>
|
92
102
|
<html>
|
93
103
|
<head>
|
94
|
-
<title>
|
104
|
+
<title>My awesome Opal app</title>
|
105
|
+
|
106
|
+
<script src="build/opal.js"></script>
|
107
|
+
<script src="build/my_awesome_app.js"></script>
|
108
|
+
|
109
|
+
<script>
|
110
|
+
// Run opal app
|
111
|
+
Opal.require('app')
|
112
|
+
</script>
|
95
113
|
</head>
|
96
114
|
<body>
|
97
|
-
<script src="opal.js"></script>
|
98
|
-
<script src="app.js"></script>
|
99
115
|
</body>
|
100
116
|
</html>
|
101
117
|
```
|
102
118
|
|
103
|
-
|
104
|
-
|
105
|
-
see the message printed to the console.
|
119
|
+
If you open the html file, observe the console and you should see
|
120
|
+
`"Hello World"` printed to the console.
|
106
121
|
|
107
|
-
|
122
|
+
It is necessary to run `Opal.require('app')` as all files built for
|
123
|
+
opal are registered so that they can be required inside the ruby
|
124
|
+
code.
|
108
125
|
|
109
|
-
|
110
|
-
opal. For more complex apps with dependencies, Opal provides useful
|
111
|
-
rake tasks to get started. Assuming opal is in your lib path, create
|
112
|
-
a `Rakefile` similar to:
|
126
|
+
### Adding dependencies
|
113
127
|
|
114
|
-
|
115
|
-
|
128
|
+
The `opal:dependencies` rake task above can be used to build gems which
|
129
|
+
are designed to run in the browser. `opal-dom` is a gem that given opal
|
130
|
+
access to the DOM in the browser.
|
116
131
|
|
117
|
-
|
132
|
+
`opal-dom` first needs to be installed as a gem (currently it is only
|
133
|
+
available from git):
|
118
134
|
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
end
|
135
|
+
```ruby
|
136
|
+
# Gemfile
|
137
|
+
gem "opal"
|
138
|
+
gem "opal-dom", :git => 'git://github.com/adambeynon/opal-dom.git'
|
124
139
|
```
|
125
140
|
|
126
|
-
|
127
|
-
dependencies.
|
128
|
-
|
129
|
-
### Building dependencies
|
130
|
-
|
131
|
-
To build the opal runtime `opal.js`, as well as `opal-spec` into
|
132
|
-
`build/`, run the simple rake task:
|
141
|
+
Then add it to the dependencies to build:
|
133
142
|
|
134
143
|
```ruby
|
135
|
-
|
144
|
+
Opal::RakeTask.new do |t|
|
145
|
+
t.files = ['app.rb']
|
146
|
+
t.dependencies = ['opal-dom']
|
147
|
+
end
|
136
148
|
```
|
137
149
|
|
138
|
-
|
139
|
-
|
140
|
-
Gemfile as `gem "opal-spec"` and run `bundle install`.
|
150
|
+
Running `rake opal:dependencies` now will also build
|
151
|
+
`build/opal-dom.js`.
|
141
152
|
|
142
|
-
|
143
|
-
|
144
|
-
To build the listed files into your application, run:
|
153
|
+
We can now update our application code:
|
145
154
|
|
146
155
|
```ruby
|
147
|
-
|
156
|
+
# app.rb
|
157
|
+
require 'opal-dom'
|
158
|
+
|
159
|
+
alert "Hello!"
|
148
160
|
```
|
149
161
|
|
150
|
-
|
151
|
-
filename, change the `name` property in the raketask.
|
162
|
+
And rebuild:
|
152
163
|
|
153
|
-
|
164
|
+
```
|
165
|
+
rake opal:build
|
166
|
+
```
|
154
167
|
|
155
|
-
|
168
|
+
And add `opal-dom` to the html page:
|
156
169
|
|
157
170
|
```html
|
158
|
-
|
159
|
-
<
|
160
|
-
<
|
161
|
-
<title>Test Opal App</title>
|
162
|
-
</head>
|
163
|
-
<body>
|
164
|
-
<script src="build/opal.js"></script>
|
165
|
-
<script src="build/opal-spec.js"></script>
|
166
|
-
<script src="build/my-first-app.js"></script>
|
167
|
-
</body>
|
168
|
-
</html>
|
171
|
+
<script src="build/opal.js"></script>
|
172
|
+
<script src="build/opal-dom.js"></script>
|
173
|
+
<script src="build/app.js"></script>
|
169
174
|
```
|
170
175
|
|
176
|
+
Now running the app should cause an alert box to display.
|
177
|
+
|
171
178
|
## Features And Implementation
|
172
179
|
|
173
180
|
Opal is a source-to-source compiler, so there is no VM as such and the
|
@@ -176,7 +183,7 @@ directly to underlying javascript features and objects where possible.
|
|
176
183
|
|
177
184
|
### Literals
|
178
185
|
|
179
|
-
**self** is always compiled to `
|
186
|
+
**self** is always compiled to `self`. Any context inside the generated
|
180
187
|
code is usually a function body; whether it be a method body, a block,
|
181
188
|
a class/module body or the file itself.
|
182
189
|
|
@@ -195,7 +202,7 @@ files points to a special object which is just an instance of the ruby
|
|
195
202
|
nil # => nil
|
196
203
|
true # => true
|
197
204
|
false # => false
|
198
|
-
self # =>
|
205
|
+
self # => self
|
199
206
|
```
|
200
207
|
|
201
208
|
#### Strings
|
@@ -262,94 +269,6 @@ range instances.
|
|
262
269
|
3...7 # => __range(3, 7, false)
|
263
270
|
```
|
264
271
|
|
265
|
-
### Classes and Modules
|
266
|
-
|
267
|
-
A compiled class or module body is simply just an anonymous javascript
|
268
|
-
function that is used to keep any internal variables from escaping.
|
269
|
-
|
270
|
-
Classes and modules themselves are created as named functions (which is
|
271
|
-
used purely to aid debugging). Classes and modules may also be
|
272
|
-
re-opended, so they are put through a runtime function `__klass` for
|
273
|
-
classes, and `__module` for modules.
|
274
|
-
|
275
|
-
For example, the `Kernel` module is generated as:
|
276
|
-
|
277
|
-
```javascript
|
278
|
-
(function(__base) {
|
279
|
-
function Kernel(){};
|
280
|
-
Kernel = __module(__base, "Kernel", Kernel);
|
281
|
-
var Kernel_prototype = Kernel.prototype;
|
282
|
-
|
283
|
-
Kernel_prototype.$class = function() {
|
284
|
-
return this._real;
|
285
|
-
};
|
286
|
-
|
287
|
-
Kernel._donate('$class', ...);
|
288
|
-
})(__scope);
|
289
|
-
```
|
290
|
-
|
291
|
-
Firstly, the `__scope` is passed into the function which is used
|
292
|
-
for defining constants, which means that if `Kernel` gets defined
|
293
|
-
here then it can be set as a constant for the given scope. The
|
294
|
-
named function (Kernel) follows, as well as the `__module()` call
|
295
|
-
which simply sets the up the module if it doesn't already exist. If
|
296
|
-
it does exist, then it overwrites the previous `Kernel` local variable.
|
297
|
-
|
298
|
-
Next, `Kernel_prototype` is made a local variable to improve
|
299
|
-
minimization of the code, then all the Kernel methods are set on the
|
300
|
-
prototype. Modules cannot be instantiated in Opal (just like ruby), but
|
301
|
-
the use of prototypes is to improve performance.
|
302
|
-
|
303
|
-
Finally, the call to `Kernel._donate()` is to pass any defined methods
|
304
|
-
into classes that have included `Kernel`, which is just `Object`. This
|
305
|
-
method then adds all of Kernels methods into Objects prototype as this
|
306
|
-
is the most efficient way to try and emulate rubys method chain.
|
307
|
-
|
308
|
-
### Methods
|
309
|
-
|
310
|
-
A ruby method is just compiled directly into a function definition.
|
311
|
-
These functions are added to the constructor's prototype so they can
|
312
|
-
be called just like any javascript function. All ruby methods are
|
313
|
-
defined with a `$` prefix to try and isolate them from javascript
|
314
|
-
methods.
|
315
|
-
|
316
|
-
#### Method Calls
|
317
|
-
|
318
|
-
All method arguments are passed to the native function just like normal
|
319
|
-
javascript function calls. Therefore, the given ruby code:
|
320
|
-
|
321
|
-
```ruby
|
322
|
-
do_something 1, 2, 3
|
323
|
-
self.length
|
324
|
-
[1, 2, 3].push 5
|
325
|
-
```
|
326
|
-
|
327
|
-
Will be compiled into the easy to read javascript:
|
328
|
-
|
329
|
-
```javascript
|
330
|
-
this.$do_something(1, 2, 3);
|
331
|
-
this.$length();
|
332
|
-
[1, 2, 3].$push(5);
|
333
|
-
```
|
334
|
-
|
335
|
-
There are some certain characters which are valid as ruby method names
|
336
|
-
but not as javascript identifiers. These method calls are encoded to
|
337
|
-
keep the generated method names sane.
|
338
|
-
|
339
|
-
```ruby
|
340
|
-
self.loaded? # => this.$loaded$p()
|
341
|
-
self.load! # => this.$load$b()
|
342
|
-
self.loaded = true # => this.$loaded$e(true)
|
343
|
-
self << :bar # => this.$lshift$("bar")
|
344
|
-
```
|
345
|
-
|
346
|
-
Finally, method calls with splat arguments are also supported:
|
347
|
-
|
348
|
-
```ruby
|
349
|
-
self.push *[1, 2, 3]
|
350
|
-
# => this.$push.apply(this, [1, 2, 3])
|
351
|
-
```
|
352
|
-
|
353
272
|
#### Optimized Math Operators
|
354
273
|
|
355
274
|
In ruby, all math operators are method calls, but compiling this into
|
@@ -364,7 +283,7 @@ if so then to just carry out the math call.
|
|
364
283
|
This ruby code will then be compiled into the following javascript:
|
365
284
|
|
366
285
|
```javascript
|
367
|
-
(a = 3, b = 4, typeof(a) === "number" ? a + b :
|
286
|
+
(a = 3, b = 4, typeof(a) === "number" ? a + b : /* method call */)
|
368
287
|
```
|
369
288
|
|
370
289
|
This ternary statement falls back on sending a method to the receiver
|
@@ -372,68 +291,10 @@ so all non-numeric receivers will still have the normal method call
|
|
372
291
|
being sent. This optimization makes math operators a **lot faster**.
|
373
292
|
Currently, the optimized method calls are `+`, `-`, `*` and `/`.
|
374
293
|
|
375
|
-
|
294
|
+
### method_missing
|
376
295
|
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
```ruby
|
381
|
-
def to_s
|
382
|
-
inspect
|
383
|
-
end
|
384
|
-
```
|
385
|
-
|
386
|
-
This would generate the following javascript. (`Array_prototype` is
|
387
|
-
an example and would assume this method definition is inside the
|
388
|
-
`Array` class body).
|
389
|
-
|
390
|
-
```javascript
|
391
|
-
Array_prototype.$to_s = function() {
|
392
|
-
return this.$inspect();
|
393
|
-
};
|
394
|
-
```
|
395
|
-
|
396
|
-
The defined name retains the `$` prefix outlined above, and the `self`
|
397
|
-
value for the method is `this`, which will be the receiver.
|
398
|
-
|
399
|
-
Normal arguments, splat args and optional args are all supported:
|
400
|
-
|
401
|
-
```ruby
|
402
|
-
def norm(a, b, c)
|
403
|
-
|
404
|
-
end
|
405
|
-
|
406
|
-
def opt(a, b = 100)
|
407
|
-
|
408
|
-
end
|
409
|
-
|
410
|
-
def rest(a, *b)
|
411
|
-
|
412
|
-
end
|
413
|
-
```
|
414
|
-
|
415
|
-
The generated code reads as expected:
|
416
|
-
|
417
|
-
```javascript
|
418
|
-
Array_prototype.$norm = function(a, b, c) {
|
419
|
-
return nil;
|
420
|
-
};
|
421
|
-
|
422
|
-
Array_prototype.$opt = function(a, b) {
|
423
|
-
if (b == null) b = 100;
|
424
|
-
return nil;
|
425
|
-
};
|
426
|
-
|
427
|
-
Array_prototype.$rest = function(a, b) {
|
428
|
-
b = __slice.call(arguments, 1);
|
429
|
-
return nil;
|
430
|
-
};
|
431
|
-
```
|
432
|
-
|
433
|
-
Currently, in opal there is no argument length checking to ensure that
|
434
|
-
the correct number of arguments get passed to a function. This can be
|
435
|
-
enabled in debug mode, but is not included in production builds as it
|
436
|
-
adds a lot of overhead to **every** method call.
|
296
|
+
Method missing is fully supported in Opal. It is implemented as
|
297
|
+
efficiently as possible.
|
437
298
|
|
438
299
|
### Logic and conditionals
|
439
300
|
|
@@ -696,6 +557,12 @@ Opal is released under the MIT license.
|
|
696
557
|
|
697
558
|
## Change Log
|
698
559
|
|
560
|
+
**0.3.21** _(16 July 2012)_
|
561
|
+
|
562
|
+
* Add `method_missing` support to all objects and classes
|
563
|
+
* Add `Opal.build_gem()` method to quickly build installed gem
|
564
|
+
* Add `Opal.build_files()` method to build directories of files
|
565
|
+
|
699
566
|
**0.3.20** _(23 June 2012)_
|
700
567
|
|
701
568
|
* Merge JSON into core. JSON module and various #to_json methods are
|