opal 0.3.11 → 0.3.15
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 +13 -0
- data/Gemfile +10 -0
- data/LICENSE +20 -0
- data/README.md +11 -116
- data/Rakefile +126 -0
- data/bin/opal +1 -2
- data/docs/spec_runner.html +16 -0
- data/index.html +434 -0
- data/lib/opal.rb +14 -15
- data/lib/opal/builder.rb +46 -148
- data/lib/opal/command.rb +45 -115
- data/lib/opal/context.rb +139 -78
- data/lib/opal/dependency_builder.rb +34 -0
- data/lib/opal/environment.rb +92 -0
- data/lib/opal/parser/grammar.rb +4915 -0
- data/lib/opal/{parser.y → parser/grammar.y} +430 -284
- data/lib/opal/parser/lexer.rb +1329 -0
- data/lib/opal/parser/parser.rb +1460 -0
- data/lib/opal/parser/scope.rb +140 -0
- data/lib/opal/parser/sexp.rb +17 -0
- data/lib/opal/version.rb +2 -1
- data/opal.gemspec +23 -0
- data/opal.js +3149 -4162
- data/runtime/README.md +25 -0
- data/runtime/corelib/alpha.rb +10 -0
- data/runtime/corelib/array.rb +962 -0
- data/runtime/corelib/basic_object.rb +66 -0
- data/runtime/corelib/boolean.rb +44 -0
- data/runtime/corelib/class.rb +43 -0
- data/runtime/corelib/comparable.rb +25 -0
- data/runtime/corelib/complex.rb +2 -0
- data/runtime/corelib/dir.rb +29 -0
- data/runtime/corelib/enumerable.rb +316 -0
- data/runtime/corelib/enumerator.rb +80 -0
- data/runtime/corelib/error.rb +25 -0
- data/runtime/corelib/file.rb +80 -0
- data/runtime/corelib/hash.rb +503 -0
- data/runtime/corelib/io.rb +44 -0
- data/runtime/corelib/kernel.rb +237 -0
- data/runtime/corelib/load_order +29 -0
- data/runtime/corelib/match_data.rb +37 -0
- data/runtime/corelib/module.rb +171 -0
- data/runtime/corelib/native.rb +50 -0
- data/runtime/corelib/nil_class.rb +47 -0
- data/runtime/corelib/numeric.rb +219 -0
- data/runtime/corelib/object.rb +21 -0
- data/runtime/corelib/proc.rb +42 -0
- data/runtime/corelib/range.rb +38 -0
- data/runtime/corelib/rational.rb +16 -0
- data/runtime/corelib/regexp.rb +63 -0
- data/runtime/corelib/string.rb +185 -0
- data/runtime/corelib/struct.rb +97 -0
- data/runtime/corelib/time.rb +196 -0
- data/runtime/corelib/top_self.rb +7 -0
- data/runtime/gemlib/alpha.rb +5 -0
- data/runtime/gemlib/kernel.rb +17 -0
- data/runtime/gemlib/load_order +2 -0
- data/runtime/kernel/class.js +256 -0
- data/runtime/kernel/debug.js +42 -0
- data/runtime/kernel/init.js +114 -0
- data/runtime/kernel/load_order +5 -0
- data/runtime/kernel/loader.js +151 -0
- data/runtime/kernel/runtime.js +414 -0
- data/runtime/spec/README.md +34 -0
- data/runtime/spec/core/array/allocate_spec.rb +15 -0
- data/runtime/spec/core/array/append_spec.rb +31 -0
- data/runtime/spec/core/array/assoc_spec.rb +29 -0
- data/runtime/spec/core/array/at_spec.rb +38 -0
- data/runtime/spec/core/array/clear_spec.rb +22 -0
- data/runtime/spec/core/array/collect_spec.rb +3 -0
- data/runtime/spec/core/array/compact_spec.rb +42 -0
- data/runtime/spec/core/array/concat_spec.rb +21 -0
- data/runtime/spec/core/array/constructor_spec.rb +24 -0
- data/runtime/spec/core/array/count_spec.rb +11 -0
- data/runtime/spec/core/array/delete_at_spec.rb +31 -0
- data/runtime/spec/core/array/delete_if_spec.rb +24 -0
- data/runtime/spec/core/array/delete_spec.rb +26 -0
- data/runtime/spec/core/array/each_index_spec.rb +33 -0
- data/runtime/spec/core/array/each_spec.rb +11 -0
- data/runtime/spec/core/array/element_reference_spec.rb +136 -0
- data/runtime/spec/core/array/element_set_spec.rb +7 -0
- data/runtime/spec/core/array/empty_spec.rb +10 -0
- data/runtime/spec/core/array/eql_spec.rb +3 -0
- data/runtime/spec/core/array/equal_value_spec.rb +3 -0
- data/runtime/spec/core/array/fetch_spec.rb +26 -0
- data/runtime/spec/core/array/first_spec.rb +54 -0
- data/runtime/spec/core/array/fixtures/classes.rb +8 -0
- data/runtime/spec/core/array/flatten_spec.rb +41 -0
- data/runtime/spec/core/array/include_spec.rb +20 -0
- data/runtime/spec/core/array/insert_spec.rb +59 -0
- data/runtime/spec/core/array/last_spec.rb +57 -0
- data/runtime/spec/core/array/length_spec.rb +3 -0
- data/runtime/spec/core/array/map_spec.rb +3 -0
- data/runtime/spec/core/array/plus_spec.rb +16 -0
- data/runtime/spec/core/array/pop_spec.rb +79 -0
- data/runtime/spec/core/array/push_spec.rb +19 -0
- data/runtime/spec/core/array/rassoc_spec.rb +12 -0
- data/runtime/spec/core/array/reject_spec.rb +54 -0
- data/runtime/spec/core/array/replace_spec.rb +3 -0
- data/runtime/spec/core/array/reverse_each_spec.rb +18 -0
- data/runtime/spec/core/array/reverse_spec.rb +9 -0
- data/runtime/spec/core/array/shared/collect.rb +53 -0
- data/runtime/spec/core/array/shared/eql.rb +19 -0
- data/runtime/spec/core/array/shared/length.rb +6 -0
- data/runtime/spec/core/array/shared/replace.rb +31 -0
- data/runtime/spec/core/class/new_spec.rb +19 -0
- data/runtime/spec/core/enumerable/all_spec.rb +102 -0
- data/runtime/spec/core/enumerable/any_spec.rb +115 -0
- data/runtime/spec/core/enumerable/collect_spec.rb +3 -0
- data/runtime/spec/core/enumerable/count_spec.rb +29 -0
- data/runtime/spec/core/enumerable/detect_spec.rb +3 -0
- data/runtime/spec/core/enumerable/find_spec.rb +3 -0
- data/runtime/spec/core/enumerable/fixtures/classes.rb +26 -0
- data/runtime/spec/core/enumerable/shared/collect.rb +12 -0
- data/runtime/spec/core/enumerable/shared/entries.rb +7 -0
- data/runtime/spec/core/enumerable/shared/find.rb +49 -0
- data/runtime/spec/core/enumerable/to_a_spec.rb +7 -0
- data/runtime/spec/core/false/and_spec.rb +11 -0
- data/runtime/spec/core/false/inspect_spec.rb +7 -0
- data/runtime/spec/core/false/or_spec.rb +11 -0
- data/runtime/spec/core/false/to_s_spec.rb +7 -0
- data/runtime/spec/core/false/xor_spec.rb +11 -0
- data/runtime/spec/core/hash/allocate_spec.rb +15 -0
- data/runtime/spec/core/hash/assoc_spec.rb +29 -0
- data/runtime/spec/core/hash/clear_spec.rb +21 -0
- data/runtime/spec/core/hash/clone_spec.rb +12 -0
- data/runtime/spec/core/hash/default_spec.rb +6 -0
- data/runtime/spec/core/hash/delete_if_spec.rb +15 -0
- data/runtime/spec/core/hash/element_reference_spec.rb +16 -0
- data/runtime/spec/core/hash/element_set_spec.rb +8 -0
- data/runtime/spec/core/hash/new_spec.rb +13 -0
- data/runtime/spec/core/matchdata/to_a_spec.rb +7 -0
- data/runtime/spec/core/nil/and_spec.rb +12 -0
- data/runtime/spec/core/nil/inspect_spec.rb +8 -0
- data/runtime/spec/core/nil/nil_spec.rb +8 -0
- data/runtime/spec/core/nil/or_spec.rb +12 -0
- data/runtime/spec/core/nil/to_a_spec.rb +8 -0
- data/runtime/spec/core/nil/to_f_spec.rb +12 -0
- data/runtime/spec/core/nil/to_i_spec.rb +12 -0
- data/runtime/spec/core/nil/to_s_spec.rb +8 -0
- data/runtime/spec/core/nil/xor_spec.rb +12 -0
- data/runtime/spec/core/numeric/equal_value_spec.rb +11 -0
- data/runtime/spec/core/object/is_a_spec.rb +2 -0
- data/runtime/spec/core/object/shared/kind_of.rb +0 -0
- data/runtime/spec/core/regexp/match_spec.rb +23 -0
- data/runtime/spec/core/regexp/shared/match.rb +11 -0
- data/runtime/spec/core/symbol/to_proc_spec.rb +8 -0
- data/runtime/spec/core/true/and_spec.rb +11 -0
- data/runtime/spec/core/true/inspect_spec.rb +7 -0
- data/runtime/spec/core/true/or_spec.rb +11 -0
- data/runtime/spec/core/true/to_s_spec.rb +7 -0
- data/runtime/spec/core/true/xor_spec.rb +11 -0
- data/runtime/spec/language/alias_spec.rb +25 -0
- data/runtime/spec/language/and_spec.rb +62 -0
- data/runtime/spec/language/array_spec.rb +68 -0
- data/runtime/spec/language/block_spec.rb +105 -0
- data/runtime/spec/language/break_spec.rb +49 -0
- data/runtime/spec/language/case_spec.rb +165 -0
- data/runtime/spec/language/defined_spec.rb +80 -0
- data/runtime/spec/language/ensure_spec.rb +82 -0
- data/runtime/spec/language/fixtures/block.rb +19 -0
- data/runtime/spec/language/fixtures/break.rb +39 -0
- data/runtime/spec/language/fixtures/defined.rb +9 -0
- data/runtime/spec/language/fixtures/ensure.rb +37 -0
- data/runtime/spec/language/fixtures/next.rb +46 -0
- data/runtime/spec/language/fixtures/send.rb +36 -0
- data/runtime/spec/language/fixtures/super.rb +43 -0
- data/runtime/spec/language/hash_spec.rb +43 -0
- data/runtime/spec/language/if_spec.rb +278 -0
- data/runtime/spec/language/loop_spec.rb +32 -0
- data/runtime/spec/language/next_spec.rb +128 -0
- data/runtime/spec/language/or_spec.rb +65 -0
- data/runtime/spec/language/predefined_spec.rb +21 -0
- data/runtime/spec/language/regexp/interpolation_spec.rb +9 -0
- data/runtime/spec/language/regexp_spec.rb +7 -0
- data/runtime/spec/language/send_spec.rb +105 -0
- data/runtime/spec/language/string_spec.rb +4 -0
- data/runtime/spec/language/super_spec.rb +18 -0
- data/runtime/spec/language/symbol_spec.rb +41 -0
- data/runtime/spec/language/undef_spec.rb +16 -0
- data/runtime/spec/language/unless_spec.rb +44 -0
- data/runtime/spec/language/until_spec.rb +137 -0
- data/runtime/spec/language/variables_spec.rb +28 -0
- data/runtime/spec/language/versions/hash_1.9.rb +20 -0
- data/runtime/spec/language/while_spec.rb +175 -0
- data/runtime/spec/library/stringscanner/scan_spec.rb +36 -0
- data/runtime/spec/opal/forwardable/def_instance_delegator_spec.rb +49 -0
- data/runtime/spec/opal/opal/defined_spec.rb +15 -0
- data/runtime/spec/opal/opal/function_spec.rb +11 -0
- data/runtime/spec/opal/opal/native_spec.rb +16 -0
- data/runtime/spec/opal/opal/null_spec.rb +10 -0
- data/runtime/spec/opal/opal/number_spec.rb +11 -0
- data/runtime/spec/opal/opal/object_spec.rb +16 -0
- data/runtime/spec/opal/opal/string_spec.rb +11 -0
- data/runtime/spec/opal/opal/typeof_spec.rb +9 -0
- data/runtime/spec/opal/opal/undefined_spec.rb +10 -0
- data/runtime/spec/opal/true/case_compare_spec.rb +12 -0
- data/runtime/spec/opal/true/class_spec.rb +10 -0
- data/runtime/spec/spec_helper.rb +25 -0
- data/runtime/stdlib/base64.rb +91 -0
- data/runtime/stdlib/date.rb +4 -0
- data/{stdlib → runtime/stdlib}/dev.rb +0 -0
- data/runtime/stdlib/forwardable.rb +33 -0
- data/runtime/stdlib/optparse.rb +0 -0
- data/runtime/stdlib/pp.rb +6 -0
- data/{stdlib → runtime/stdlib}/racc/parser.rb +0 -0
- data/runtime/stdlib/rbconfig.rb +0 -0
- data/runtime/stdlib/si.rb +17 -0
- data/runtime/stdlib/strscan.rb +53 -0
- data/runtime/stdlib/uri.rb +111 -0
- data/runtime/stdlib/uri/common.rb +1014 -0
- data/runtime/stdlib/uri/ftp.rb +261 -0
- data/runtime/stdlib/uri/generic.rb +1599 -0
- data/runtime/stdlib/uri/http.rb +106 -0
- data/runtime/stdlib/uri/https.rb +22 -0
- data/runtime/stdlib/uri/ldap.rb +260 -0
- data/runtime/stdlib/uri/ldaps.rb +20 -0
- data/runtime/stdlib/uri/mailto.rb +280 -0
- data/spec/builder/build_source_spec.rb +52 -0
- data/spec/builder/fixtures/build_source/adam.rb +0 -0
- data/spec/builder/fixtures/build_source/bar/a.rb +0 -0
- data/spec/builder/fixtures/build_source/bar/wow/b.rb +0 -0
- data/spec/builder/fixtures/build_source/bar/wow/cow/c.rb +0 -0
- data/spec/builder/fixtures/build_source/beynon.rb +0 -0
- data/spec/builder/fixtures/build_source/charles.js +0 -0
- data/spec/builder/fixtures/build_source/foo/a.rb +0 -0
- data/spec/builder/fixtures/build_source/foo/b.rb +0 -0
- data/spec/builder/fixtures/build_source/foo/x.js +0 -0
- data/spec/builder/fixtures/build_source/foo/y.js +0 -0
- data/spec/builder/output_path_spec.rb +50 -0
- data/spec/grammar/alias_spec.rb +26 -0
- data/spec/grammar/and_spec.rb +13 -0
- data/spec/grammar/array_spec.rb +22 -0
- data/spec/grammar/attrasgn_spec.rb +28 -0
- data/spec/grammar/begin_spec.rb +38 -0
- data/spec/grammar/block_spec.rb +12 -0
- data/spec/grammar/break_spec.rb +17 -0
- data/spec/grammar/call_spec.rb +58 -0
- data/spec/grammar/class_spec.rb +35 -0
- data/spec/grammar/const_spec.rb +13 -0
- data/spec/grammar/cvar_spec.rb +11 -0
- data/spec/grammar/def_spec.rb +60 -0
- data/spec/grammar/false_spec.rb +17 -0
- data/spec/grammar/file_spec.rb +7 -0
- data/spec/grammar/gvar_spec.rb +13 -0
- data/spec/grammar/hash_spec.rb +17 -0
- data/spec/grammar/iasgn_spec.rb +9 -0
- data/spec/grammar/if_spec.rb +26 -0
- data/spec/grammar/iter_spec.rb +59 -0
- data/spec/grammar/ivar_spec.rb +9 -0
- data/spec/grammar/lasgn_spec.rb +8 -0
- data/spec/grammar/line_spec.rb +8 -0
- data/spec/grammar/lvar_spec.rb +38 -0
- data/spec/grammar/module_spec.rb +27 -0
- data/spec/grammar/nil_spec.rb +17 -0
- data/spec/grammar/not_spec.rb +27 -0
- data/spec/grammar/op_asgn1_spec.rb +23 -0
- data/spec/grammar/op_asgn2_spec.rb +23 -0
- data/spec/grammar/or_spec.rb +13 -0
- data/spec/grammar/return_spec.rb +17 -0
- data/spec/grammar/sclass_spec.rb +20 -0
- data/spec/grammar/self_spec.rb +17 -0
- data/spec/grammar/str_spec.rb +96 -0
- data/spec/grammar/super_spec.rb +20 -0
- data/spec/grammar/true_spec.rb +17 -0
- data/spec/grammar/undef_spec.rb +15 -0
- data/spec/grammar/unless_spec.rb +13 -0
- data/spec/grammar/while_spec.rb +15 -0
- data/spec/grammar/xstr_spec.rb +116 -0
- data/spec/grammar/yield_spec.rb +20 -0
- data/spec/spec_helper.rb +9 -0
- metadata +346 -21
- data/lib/opal/bundle.rb +0 -34
- data/lib/opal/lexer.rb +0 -902
- data/lib/opal/nodes.rb +0 -2150
- data/lib/opal/parser.rb +0 -4894
- data/lib/opal/rake/bundle_task.rb +0 -63
- data/opal-parser.js +0 -8343
- data/stdlib/strscan.rb +0 -52
- data/templates/init/Rakefile +0 -7
- data/templates/init/index.html +0 -17
- data/templates/init/lib/__NAME__.rb +0 -2
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Copyright (C) 2011 by Adam Beynon
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
5
|
+
in the Software without restriction, including without limitation the rights
|
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
8
|
+
furnished to do so, subject to the following conditions:
|
|
9
|
+
|
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
|
11
|
+
all copies or substantial portions of the Software.
|
|
12
|
+
|
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
19
|
+
THE SOFTWARE.
|
|
20
|
+
|
data/README.md
CHANGED
|
@@ -1,122 +1,17 @@
|
|
|
1
1
|
Opal
|
|
2
2
|
====
|
|
3
3
|
|
|
4
|
-
Opal is a
|
|
5
|
-
javascript
|
|
6
|
-
|
|
7
|
-
them as fast as possible.
|
|
4
|
+
Opal is a ruby to javascript compiler. Opal aims to take ruby files and generate
|
|
5
|
+
efficient javascript that maintains rubys features. Opal will, by default,
|
|
6
|
+
generate fast and efficient code in preference to keeping all ruby features.
|
|
8
7
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
Opal comes with an implementation of the ruby corelib, written in ruby, that
|
|
9
|
+
uses a bundled runtime (written in javascript) that tie all the features
|
|
10
|
+
together. Whenever possible Opal bridges to native javascript features under
|
|
11
|
+
the hood. The Opal gem includes the compiler used to convert ruby sources
|
|
12
|
+
into javascript.
|
|
12
13
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
Opal does not aim to be 100% comaptible with other ruby implementations,
|
|
17
|
-
but does so where the generated code can be efficient on all modern web
|
|
18
|
-
browsers - including older versions of IE and mobile devices.
|
|
19
|
-
|
|
20
|
-
Installing opal
|
|
21
|
-
----------
|
|
22
|
-
|
|
23
|
-
Install the gem:
|
|
24
|
-
|
|
25
|
-
```
|
|
26
|
-
$ gem install opal
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
The `opal` command should then be available. To run the simple repl use:
|
|
30
|
-
|
|
31
|
-
```
|
|
32
|
-
opal irb
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
Usage
|
|
36
|
-
-----
|
|
37
|
-
|
|
38
|
-
The quickest way to get opal running is to use the project generator.
|
|
39
|
-
Simply run the command:
|
|
40
|
-
|
|
41
|
-
```
|
|
42
|
-
opal init my_project
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
replacing "my_project" with any name. This will make a "my_project"
|
|
46
|
-
directory with a Rakefile, html document and libs needed for running
|
|
47
|
-
opal in the browser.
|
|
48
|
-
|
|
49
|
-
### Using opal in the browser
|
|
50
|
-
|
|
51
|
-
Opal runs directly in the browser, and is distributed as two files,
|
|
52
|
-
`opal.js` and `opal-parser.js`. To just run precompiled code, just the
|
|
53
|
-
`opal.js` runtime is required which includes the runtime and opals
|
|
54
|
-
implementation of the ruby core library (pre compiled).
|
|
55
|
-
|
|
56
|
-
To evaluate ruby code directly in the browser, `opal-parser.js` is also
|
|
57
|
-
required which will also load any ruby code found in script tags.
|
|
58
|
-
|
|
59
|
-
### Bundle
|
|
60
|
-
|
|
61
|
-
The Rakefile has a task to build your ruby project, so just run:
|
|
62
|
-
|
|
63
|
-
```
|
|
64
|
-
rake bundle
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
Open `index.html` in a browser, and now it should run. Edit, build and
|
|
68
|
-
run to suit.
|
|
69
|
-
|
|
70
|
-
Project structure
|
|
71
|
-
-----------------
|
|
72
|
-
|
|
73
|
-
This repo contains the code for the opal gem as well as the opal core
|
|
74
|
-
library and runtime. Files inside `bin/` and `lib/` are the files that
|
|
75
|
-
are used as part of the gem and run directly on your ruby environment.
|
|
76
|
-
|
|
77
|
-
`corelib/` contains opal's core library implementation and is not used
|
|
78
|
-
directly by the gem. These files are precompiled during development
|
|
79
|
-
ready to be used in the gem or in a browser.
|
|
80
|
-
|
|
81
|
-
`runtime/` contains opal's runtime written in javascript. It is not used
|
|
82
|
-
directly by the gem, but is built ready to use in the js contexts that
|
|
83
|
-
opal runs.
|
|
84
|
-
|
|
85
|
-
`stdlib/` contains the stdlib files that opal comes packaged with. The
|
|
86
|
-
gem does use these, but only as required. Opal does not include the full
|
|
87
|
-
opal stdlib, and some parts are actually written in javascript for
|
|
88
|
-
optimal performance. These can be `require()` at runtime.
|
|
89
|
-
|
|
90
|
-
`opal.js` and `opal-parser.js` are included in the gem, but not the
|
|
91
|
-
source repo. They are the latest built versions of opal and its parser
|
|
92
|
-
which are built before the gem is published.
|
|
93
|
-
|
|
94
|
-
Differences from ruby
|
|
95
|
-
---------------------
|
|
96
|
-
|
|
97
|
-
### Optional method\_missing
|
|
98
|
-
|
|
99
|
-
To optimize method dispatch, `method_missing` is, by default, turned off
|
|
100
|
-
in opal. It can easily be enabled by passing `:method_missing => true`
|
|
101
|
-
in the parser options.
|
|
102
|
-
|
|
103
|
-
### Immutable strings and removed symbols
|
|
104
|
-
|
|
105
|
-
All strings in opal are immutable to make them easier to map onto
|
|
106
|
-
javascript strings. In opal a ruby string compiles directly into a js
|
|
107
|
-
string without a wrapper so that they can be passed back between code
|
|
108
|
-
bases easily. Also, symbol syntax is maintained, but all symbols just
|
|
109
|
-
compile into javascript strings. The `Symbol` class is also therefore
|
|
110
|
-
removed.
|
|
111
|
-
|
|
112
|
-
### Unified Numeric class
|
|
113
|
-
|
|
114
|
-
All numbers in opal are members of the `Numeric` class. The `Integer`
|
|
115
|
-
and `Float` classes are removed.
|
|
116
|
-
|
|
117
|
-
### Unified Boolean class
|
|
118
|
-
|
|
119
|
-
Both `true` and `false` compile into their native javascript
|
|
120
|
-
counterparts which means that they both become instances of the
|
|
121
|
-
`Boolean` class and opal removes the `TrueClass` and `FalseClass`.
|
|
14
|
+
For docs, visit the website:
|
|
15
|
+
[http://adambeynon.github.com/opal](http://adambeynon.github.com/opal)
|
|
122
16
|
|
|
17
|
+
Join the IRC channel on Freenode: `#opal`.
|
data/Rakefile
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
require 'bundler/setup'
|
|
2
|
+
require 'bundler/gem_tasks'
|
|
3
|
+
require 'opal'
|
|
4
|
+
require 'fileutils'
|
|
5
|
+
require 'opal/version'
|
|
6
|
+
|
|
7
|
+
namespace :browser do
|
|
8
|
+
desc "Build opal runtime to opal.js"
|
|
9
|
+
task :opal do
|
|
10
|
+
File.open("opal.js", 'w+') { |o| o.write build_runtime false }
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
desc "Build opal debug runtime to opal.debug.js"
|
|
14
|
+
task :debug do
|
|
15
|
+
File.open("opal.debug.js", 'w+') { |o| o.write build_runtime true }
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
desc "Tests for browser to opal.test.js"
|
|
19
|
+
task :test do
|
|
20
|
+
Opal::Builder.new('runtime/spec', :join => 'opal.test.js').build
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
desc "Build dependencies into runtime/"
|
|
24
|
+
task :dependencies do
|
|
25
|
+
Opal::DependencyBuilder.new(:out => 'runtime').build
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
desc "Build opal and debug opal into runtime/"
|
|
30
|
+
task :browser => [:'browser:opal', :'browser:debug']
|
|
31
|
+
|
|
32
|
+
desc "Run opal specs (from runtime/spec/*)"
|
|
33
|
+
task :test => :browser do
|
|
34
|
+
Opal::Context.runner 'runtime/spec/**/*.rb'
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
desc "Check file sizes for core builds"
|
|
38
|
+
task :sizes do
|
|
39
|
+
sizes 'runtime/opal.js'
|
|
40
|
+
sizes 'runtime/opal.debug.js'
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
desc "Rebuild grammar.rb for opal parser"
|
|
44
|
+
task :parser do
|
|
45
|
+
%x(racc -l lib/opal/parser/grammar.y -o lib/opal/parser/grammar.rb)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
namespace :docs do
|
|
49
|
+
task :clone do
|
|
50
|
+
if File.exists? 'gh-pages'
|
|
51
|
+
Dir.chdir('gh-pages') { sh 'git pull origin gh-pages' }
|
|
52
|
+
else
|
|
53
|
+
FileUtils.mkdir_p 'gh-pages'
|
|
54
|
+
Dir.chdir('gh-pages') do
|
|
55
|
+
sh 'git clone git@github.com:/adambeynon/opal.git .'
|
|
56
|
+
sh 'git checkout gh-pages'
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
desc "Copy required files into gh-pages dir"
|
|
62
|
+
task :copy => :browser do
|
|
63
|
+
%w[opal.js opal.debug.js index.html].each do |f|
|
|
64
|
+
FileUtils.cp f, "gh-pages/#{f}"
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
HEADER = <<-HEADER
|
|
70
|
+
/*!
|
|
71
|
+
* opal v#{Opal::VERSION}
|
|
72
|
+
* http://adambeynon.github.com/opal
|
|
73
|
+
*
|
|
74
|
+
* Copyright 2012, Adam Beynon
|
|
75
|
+
* Released under the MIT license
|
|
76
|
+
*/
|
|
77
|
+
HEADER
|
|
78
|
+
|
|
79
|
+
def build_runtime debug = false
|
|
80
|
+
rborder = File.read('runtime/corelib/load_order').strip.split
|
|
81
|
+
rbcore = rborder.map { |c| File.read "runtime/corelib/#{c}.rb" }
|
|
82
|
+
jsorder = File.read('runtime/kernel/load_order').strip.split
|
|
83
|
+
jscore = jsorder.map { |c| File.read "runtime/kernel/#{c}.js" }
|
|
84
|
+
|
|
85
|
+
parser = Opal::Parser.new :debug => debug
|
|
86
|
+
parsed = parser.parse rbcore.join("\n"), '(corelib)'
|
|
87
|
+
methods = Opal::Parser::METHOD_NAMES.map { |f, t| "'#{f}': 'm$#{t}$'" }
|
|
88
|
+
result = []
|
|
89
|
+
|
|
90
|
+
result << '(function(undefined) {'
|
|
91
|
+
result << jscore.join
|
|
92
|
+
result << "var method_names = {#{methods.join ', '}};"
|
|
93
|
+
result << "var reverse_method_names = {}; for (var id in method_names) {"
|
|
94
|
+
result << "reverse_method_names[method_names[id]] = id;}"
|
|
95
|
+
result << parsed
|
|
96
|
+
result << '}).call(this);'
|
|
97
|
+
|
|
98
|
+
HEADER + result.join("\n")
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def sizes file
|
|
102
|
+
o = File.read file
|
|
103
|
+
m = uglify o
|
|
104
|
+
g = gzip m
|
|
105
|
+
|
|
106
|
+
puts "#{file}:"
|
|
107
|
+
puts "development: #{o.size}, minified: #{m.size}, gzipped: #{g.size}"
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# Used for uglifying source to minify
|
|
111
|
+
def uglify(str)
|
|
112
|
+
IO.popen('uglifyjs -nc', 'r+') do |i|
|
|
113
|
+
i.puts str
|
|
114
|
+
i.close_write
|
|
115
|
+
return i.read
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
# Gzip code to check file size
|
|
120
|
+
def gzip(str)
|
|
121
|
+
IO.popen('gzip -f', 'r+') do |i|
|
|
122
|
+
i.puts str
|
|
123
|
+
i.close_write
|
|
124
|
+
return i.read
|
|
125
|
+
end
|
|
126
|
+
end
|
data/bin/opal
CHANGED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<meta http-equiv="content-type" content="text/html; charset=utf-8">
|
|
5
|
+
|
|
6
|
+
<title>Opal Spec Runner</title>
|
|
7
|
+
</head>
|
|
8
|
+
<body>
|
|
9
|
+
<script src="../opal.debug.js"></script>
|
|
10
|
+
<script src="../opal-spec.js"></script>
|
|
11
|
+
<script src="../opal.test.js"></script>
|
|
12
|
+
<script>
|
|
13
|
+
opal.main('/runtime/spec/spec_helper.rb');
|
|
14
|
+
</script>
|
|
15
|
+
</body>
|
|
16
|
+
</html>
|
data/index.html
ADDED
|
@@ -0,0 +1,434 @@
|
|
|
1
|
+
<!DOCTYPE HTML>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
|
5
|
+
|
|
6
|
+
<title>Opal</title>
|
|
7
|
+
<style>
|
|
8
|
+
body {
|
|
9
|
+
line-height: 22px;
|
|
10
|
+
font-size: 14px;
|
|
11
|
+
font-family: Helvetica Neue, Helvetica, Arial, sans-serif;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.content {
|
|
15
|
+
padding: 50px 50px 50px 50px;
|
|
16
|
+
width: 650px;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
p {
|
|
20
|
+
width: 650px;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
pre, code {
|
|
24
|
+
font-family: "Bitstream Vera Sans Mono", Monaco, "Lucida Console", monospace;
|
|
25
|
+
font-size: 12px;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
pre {
|
|
29
|
+
line-height: 17px;
|
|
30
|
+
color: #444444;
|
|
31
|
+
white-space: pre;
|
|
32
|
+
padding: 3px 0px 3px 12px;
|
|
33
|
+
margin: 0px 0px 8px;
|
|
34
|
+
|
|
35
|
+
background: #FAFAFA;
|
|
36
|
+
-webkit-box-shadow: rgba(0,0,0,0.07) 0 1px 2px inset;
|
|
37
|
+
-webkit-border-radius: 3px;
|
|
38
|
+
-moz-border-radius: 3px;
|
|
39
|
+
border-radius: 3px;
|
|
40
|
+
border: 1px solid #DDDDDD;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
code {
|
|
44
|
+
background-color: #FAFAFA;
|
|
45
|
+
padding: 1px;
|
|
46
|
+
color: #444444;
|
|
47
|
+
border: 1px solid #DEDEDE;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
pre code {
|
|
51
|
+
border: none;
|
|
52
|
+
padding: 0px;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
a {
|
|
56
|
+
color: #212121;
|
|
57
|
+
}
|
|
58
|
+
</style>
|
|
59
|
+
</head>
|
|
60
|
+
<body>
|
|
61
|
+
<div class="content">
|
|
62
|
+
<h1 id='opal'>Opal</h1>
|
|
63
|
+
|
|
64
|
+
<p>
|
|
65
|
+
<strong>Opal is a ruby to javascript compiler</strong>. Opal aims to
|
|
66
|
+
take ruby files and generate efficient javascript that maintains rubys
|
|
67
|
+
features. Opal will, by default, generate fast and efficient code in
|
|
68
|
+
preference to keeping all ruby features.
|
|
69
|
+
</p>
|
|
70
|
+
|
|
71
|
+
<p>
|
|
72
|
+
Opal comes with an implementation of the ruby corelib, written in ruby,
|
|
73
|
+
that uses a bundled runtime (written in javascript) that tie all the
|
|
74
|
+
features together. Whenever possible Opal bridges to native javascript
|
|
75
|
+
features under the hood. The Opal gem includes the compiler used to
|
|
76
|
+
convert ruby sources into javascript.
|
|
77
|
+
</p>
|
|
78
|
+
|
|
79
|
+
<p>
|
|
80
|
+
Opal is <a href='http://github.com/adambeynon/opal'>hosted on github</a>,
|
|
81
|
+
and there is a Freenode IRC channel at <code>#opal</code>.
|
|
82
|
+
</p>
|
|
83
|
+
|
|
84
|
+
<h2 id='downloads'>Downloads</h2>
|
|
85
|
+
|
|
86
|
+
<p>
|
|
87
|
+
The Opal runtime and corelib are distributed here, and are required to
|
|
88
|
+
run any code generated by opal.
|
|
89
|
+
</p>
|
|
90
|
+
|
|
91
|
+
<p>
|
|
92
|
+
<strong>Production</strong> version to be used in real apps/sites.
|
|
93
|
+
</p>
|
|
94
|
+
|
|
95
|
+
<p>
|
|
96
|
+
<a href='http://adambeynon.github.com/opal/opal.js'>
|
|
97
|
+
Production version 0.3.15
|
|
98
|
+
</a>
|
|
99
|
+
<em>(120kb Uncompressed, 13.7kb Minified And Gzipped)</em>
|
|
100
|
+
</p>
|
|
101
|
+
|
|
102
|
+
<p>
|
|
103
|
+
<strong>Debug</strong> version adds a lot of additional debug code.
|
|
104
|
+
See the debug section below.
|
|
105
|
+
</p>
|
|
106
|
+
|
|
107
|
+
<p>
|
|
108
|
+
<a href='http://adambeynon.github.com/opal/opal.debug.js'>
|
|
109
|
+
Debug version 0.3.15
|
|
110
|
+
</a>
|
|
111
|
+
<em>(183kb Uncompressed)</em>
|
|
112
|
+
</p>
|
|
113
|
+
|
|
114
|
+
<h2 id='installation'>Installation</h2>
|
|
115
|
+
|
|
116
|
+
<p>Opal comes distributed as a gem, so either install with:</p>
|
|
117
|
+
|
|
118
|
+
<pre><code>gem install opal</code></pre>
|
|
119
|
+
|
|
120
|
+
<p>Or add to your Gemfile:</p>
|
|
121
|
+
|
|
122
|
+
<pre><code>gem "opal"</code></pre>
|
|
123
|
+
|
|
124
|
+
<h2 id='usage'>Usage</h2>
|
|
125
|
+
|
|
126
|
+
<p>
|
|
127
|
+
Opal provides an <code>opal</code> command which can be used to
|
|
128
|
+
compile ruby sources into javascript. These can then be used in
|
|
129
|
+
any browser/javascript environment. Opal also comes with the
|
|
130
|
+
ability to run files direcly using
|
|
131
|
+
<a href='http://github.com/cowboyd/therubyracer'>therubyracer</a>,
|
|
132
|
+
which is a gem to embed v8 into ruby. This also allows Opal to provide
|
|
133
|
+
a REPL to run ruby code directly against the Opal runtime.
|
|
134
|
+
</p>
|
|
135
|
+
|
|
136
|
+
<h3 id='repl'>REPL</h3>
|
|
137
|
+
|
|
138
|
+
<p>To run the ruby repl, simply run:</p>
|
|
139
|
+
|
|
140
|
+
<pre><code>opal</code></pre>
|
|
141
|
+
|
|
142
|
+
<p>from the command line. To exit, type <code>exit</code>.</p>
|
|
143
|
+
|
|
144
|
+
<h3 id='running_a_ruby_file'>Running a ruby file</h3>
|
|
145
|
+
|
|
146
|
+
<p>
|
|
147
|
+
Opal can compile/eval any ruby file inside the v8 context by simply
|
|
148
|
+
passing a path to run:
|
|
149
|
+
</p>
|
|
150
|
+
|
|
151
|
+
<pre><code>opal path/to/file.rb</code></pre>
|
|
152
|
+
|
|
153
|
+
<p>Try running some code with <code>puts</code> statements.</p>
|
|
154
|
+
|
|
155
|
+
<h3 id='compiling_ruby_sources'>Compiling Ruby Sources</h3>
|
|
156
|
+
|
|
157
|
+
<p>If you have a ruby source <code>foo.rb</code>:</p>
|
|
158
|
+
|
|
159
|
+
<pre>
|
|
160
|
+
# foo.rb
|
|
161
|
+
|
|
162
|
+
puts "Wow, running ruby"
|
|
163
|
+
</pre>
|
|
164
|
+
|
|
165
|
+
<p>Compile it into <code>foo.js</code> using:</p>
|
|
166
|
+
|
|
167
|
+
<pre>
|
|
168
|
+
opal -c foo.rb
|
|
169
|
+
</pre>
|
|
170
|
+
|
|
171
|
+
<p>
|
|
172
|
+
The generated code includes a wrapper which will register the
|
|
173
|
+
file with opal. Opal maintains an internal file system to make
|
|
174
|
+
<code>require()</code> work as expected. You will see this in
|
|
175
|
+
the output:
|
|
176
|
+
</p>
|
|
177
|
+
|
|
178
|
+
<pre>
|
|
179
|
+
// foo.js
|
|
180
|
+
opal.file('foo.rb', function() {
|
|
181
|
+
// compiled ruby code
|
|
182
|
+
});
|
|
183
|
+
</pre>
|
|
184
|
+
|
|
185
|
+
<p>
|
|
186
|
+
This file is not enough to run by itself. It depends on
|
|
187
|
+
<code>opal.js</code> which can be downloaded above. Finally,
|
|
188
|
+
compiling a ruby source creates a wrapper around the code which
|
|
189
|
+
will register the file with the opal runtime. To actually load
|
|
190
|
+
this code, you can use the <code>main()</code> function:
|
|
191
|
+
</p>
|
|
192
|
+
|
|
193
|
+
<pre>
|
|
194
|
+
opal.main('foo');
|
|
195
|
+
</pre>
|
|
196
|
+
|
|
197
|
+
<p>These files can be added to a HTML page:</p>
|
|
198
|
+
|
|
199
|
+
<pre>
|
|
200
|
+
<!DOCTYPE html>
|
|
201
|
+
<html>
|
|
202
|
+
<head>
|
|
203
|
+
<script src="opal.js"></script>
|
|
204
|
+
<script src="foo.js"></script>
|
|
205
|
+
<script>
|
|
206
|
+
opal.main('foo');
|
|
207
|
+
</script>
|
|
208
|
+
</head>
|
|
209
|
+
<body>
|
|
210
|
+
|
|
211
|
+
</body>
|
|
212
|
+
</html>
|
|
213
|
+
</pre>
|
|
214
|
+
|
|
215
|
+
<p>Open this file and check out the browsers' console.</p>
|
|
216
|
+
|
|
217
|
+
<h2 id='generated_code'>Generated Code</h2>
|
|
218
|
+
|
|
219
|
+
<p>
|
|
220
|
+
The Opal compiler is a source-to-source compiler; it reads in ruby
|
|
221
|
+
code and ouputs javascript code. The generated code makes use of native
|
|
222
|
+
javascript features when possible, and all code is output to the same
|
|
223
|
+
line number as the source. This, along with correctly indented output,
|
|
224
|
+
makes debugging very easy.
|
|
225
|
+
</p>
|
|
226
|
+
|
|
227
|
+
<h3 id='ruby_literals'>Ruby Literals</h3>
|
|
228
|
+
|
|
229
|
+
<h4 id='literals'>Literals</h4>
|
|
230
|
+
|
|
231
|
+
<p>
|
|
232
|
+
<strong>self</strong> is always compiled to <code>this</code> in
|
|
233
|
+
javascript which makes the generated code a lot cleaner to use. All
|
|
234
|
+
methods, blocks, classes, modules and top level code correctly have
|
|
235
|
+
their <code>this</code> value set.
|
|
236
|
+
</p>
|
|
237
|
+
|
|
238
|
+
<p>
|
|
239
|
+
<strong>true</strong> and <strong>false</strong> are also compiled into
|
|
240
|
+
their native javascript equivalents. This makes interacting with
|
|
241
|
+
external libraries a lot easier as there is no need to convert to
|
|
242
|
+
special ruby values.
|
|
243
|
+
</p>
|
|
244
|
+
|
|
245
|
+
<p>
|
|
246
|
+
<strong>nil</strong> is compiled into a special ruby object (an instance
|
|
247
|
+
of NilClass). A real object is used (instead of null and undefined) as
|
|
248
|
+
this allows nil to receive method calls which is a crucial ruby feature
|
|
249
|
+
which Opal maintains.
|
|
250
|
+
</p>
|
|
251
|
+
|
|
252
|
+
<h4 id='strings'>Strings</h4>
|
|
253
|
+
|
|
254
|
+
<p>
|
|
255
|
+
Ruby strings are compiled directly into javascript strings, for
|
|
256
|
+
performance as well as readability. This has the side affect that Opal
|
|
257
|
+
does not support mutable strings - all strings are immutable.
|
|
258
|
+
</p>
|
|
259
|
+
|
|
260
|
+
<h4 id='symbols'>Symbols</h4>
|
|
261
|
+
|
|
262
|
+
<p>
|
|
263
|
+
For performance reasons, Symbols compile into the string equivalents.
|
|
264
|
+
Opal supports the symbol syntax(es), but does not have a real Symbol
|
|
265
|
+
class. The Symbol constant is just an alias of String. Strings and
|
|
266
|
+
Symbols can be used in Opal interchangeably.
|
|
267
|
+
</p>
|
|
268
|
+
|
|
269
|
+
<h4 id='numbers'>Numbers</h4>
|
|
270
|
+
|
|
271
|
+
<p>
|
|
272
|
+
In Opal there is a single class for all numbers; <code>Numeric</code>.
|
|
273
|
+
To keep Opal as performant as possible, native javascript strings are
|
|
274
|
+
used. This has the side effect that all numbers must be an instance of
|
|
275
|
+
a single class. Most relevant methods from <code>Integer</code>,
|
|
276
|
+
<code>Float</code> and <code>Numeric</code> are implemented on this
|
|
277
|
+
class.
|
|
278
|
+
</p>
|
|
279
|
+
|
|
280
|
+
<h4 id='arrays'>Arrays</h4>
|
|
281
|
+
|
|
282
|
+
<p>Ruby arrays compile straight into javascript array literals.</p>
|
|
283
|
+
|
|
284
|
+
<h4 id='hash'>Hash</h4>
|
|
285
|
+
|
|
286
|
+
<p>
|
|
287
|
+
There is a special constructor available inside generated sources,
|
|
288
|
+
<code>$hash</code> which is used to create hash instances.
|
|
289
|
+
</p>
|
|
290
|
+
|
|
291
|
+
<h4 id='range'>Range</h4>
|
|
292
|
+
|
|
293
|
+
<p>
|
|
294
|
+
Similarly to hashes, the <code>$range</code> constructor can be used
|
|
295
|
+
to create new range instances.
|
|
296
|
+
</p>
|
|
297
|
+
|
|
298
|
+
<h3 id='ruby_methods'>Ruby Methods</h3>
|
|
299
|
+
|
|
300
|
+
<p>
|
|
301
|
+
A ruby method is just a function in the generated code. These functions
|
|
302
|
+
are added to the constructor’s prototypes so they are called just
|
|
303
|
+
like any other javascript function. All ruby methods are defined with
|
|
304
|
+
an <code>m$</code> prefix which isolates them from any javascript
|
|
305
|
+
function/property on the receiver.
|
|
306
|
+
</p>
|
|
307
|
+
|
|
308
|
+
<h4 id='method_calls'>Method Calls</h4>
|
|
309
|
+
|
|
310
|
+
<p>
|
|
311
|
+
All arguments are added to regular javascript function calls with the
|
|
312
|
+
addition of a block argument. If a block is given, then it will be the
|
|
313
|
+
first argument in the call. If no block is given then the first argument
|
|
314
|
+
will be null. This block argument is invisible to the ruby code.
|
|
315
|
+
</p>
|
|
316
|
+
|
|
317
|
+
<p>The following ruby code:</p>
|
|
318
|
+
|
|
319
|
+
<pre>
|
|
320
|
+
do_something 1, 2, 3
|
|
321
|
+
self.length
|
|
322
|
+
[1, 2, 3].push 5
|
|
323
|
+
</pre>
|
|
324
|
+
|
|
325
|
+
<p>Will therefore compile into the following easy to read javascript:</p>
|
|
326
|
+
|
|
327
|
+
<pre>
|
|
328
|
+
this.m$do_something(null, 1, 2, 3);
|
|
329
|
+
this.m$length();
|
|
330
|
+
[1, 2, 3].m$push(null, 5);
|
|
331
|
+
</pre>
|
|
332
|
+
|
|
333
|
+
<p>
|
|
334
|
+
There are of course some special characters valid as ruby names that are
|
|
335
|
+
not valid as javascript identifiers. These are specially encoded to keep
|
|
336
|
+
the generated javascript sane:
|
|
337
|
+
</p>
|
|
338
|
+
|
|
339
|
+
<pre>
|
|
340
|
+
this.loaded? # => this.m$loaded$p()
|
|
341
|
+
this.load! # => this.m$load$b()
|
|
342
|
+
this.loaded = true # => this.m$loaded$e(null, true)
|
|
343
|
+
</pre>
|
|
344
|
+
|
|
345
|
+
<p>Call arguments with splats are also supported.</p>
|
|
346
|
+
|
|
347
|
+
<pre>
|
|
348
|
+
this.push *[1, 2, 3]
|
|
349
|
+
# => this.m$push.apply(this, [null].concat([1, 2, 3])
|
|
350
|
+
</pre>
|
|
351
|
+
|
|
352
|
+
<p>When a block argument is given, it will be added as the first call arg.</p>
|
|
353
|
+
|
|
354
|
+
<pre>
|
|
355
|
+
describe "some test" do; ... end
|
|
356
|
+
# => this.m$describe(function() { ... }, "some test")
|
|
357
|
+
</pre>
|
|
358
|
+
|
|
359
|
+
<h4 id='method_definitions'>Method Definitions</h4>
|
|
360
|
+
|
|
361
|
+
<p>
|
|
362
|
+
Methods are implemented as regular javascript functions. Assuming the
|
|
363
|
+
following method definition defined inside a class body:
|
|
364
|
+
</p>
|
|
365
|
+
|
|
366
|
+
<pre>
|
|
367
|
+
def to_s
|
|
368
|
+
inspect
|
|
369
|
+
end
|
|
370
|
+
</pre>
|
|
371
|
+
|
|
372
|
+
<p>
|
|
373
|
+
This would generate the following javascript (<code>$proto</code> will
|
|
374
|
+
be explained in the Class documentation):
|
|
375
|
+
</p>
|
|
376
|
+
|
|
377
|
+
<pre>
|
|
378
|
+
$proto.m$to_s = function() {
|
|
379
|
+
return this.m$inspect();
|
|
380
|
+
};
|
|
381
|
+
</pre>
|
|
382
|
+
|
|
383
|
+
<p>
|
|
384
|
+
The defined name retains the <code>m$</code> prefix outlined above,
|
|
385
|
+
and the <code>self</code> value for the method is <code>this</code>,
|
|
386
|
+
which will be the receiver.
|
|
387
|
+
</p>
|
|
388
|
+
|
|
389
|
+
<p>Normal arguments, splat args and optional args are all supported:</p>
|
|
390
|
+
|
|
391
|
+
<pre>
|
|
392
|
+
def norm(a, b, c)
|
|
393
|
+
|
|
394
|
+
end
|
|
395
|
+
|
|
396
|
+
def opt(a, b = 100)
|
|
397
|
+
|
|
398
|
+
end
|
|
399
|
+
|
|
400
|
+
def rest(a, *b)
|
|
401
|
+
|
|
402
|
+
end
|
|
403
|
+
</pre>
|
|
404
|
+
|
|
405
|
+
<p>
|
|
406
|
+
The generated code includes an empty block definition
|
|
407
|
+
<code>$block</code> which will not be used as this method does not
|
|
408
|
+
yield to a block:
|
|
409
|
+
</p>
|
|
410
|
+
|
|
411
|
+
<pre>
|
|
412
|
+
$proto.m$norm = function($block, a, b, c) {
|
|
413
|
+
return nil;
|
|
414
|
+
};
|
|
415
|
+
|
|
416
|
+
$proto.m$opt = function($block, a, b) {
|
|
417
|
+
if (b === undefined) b = 10;
|
|
418
|
+
return nil;
|
|
419
|
+
};
|
|
420
|
+
|
|
421
|
+
$proto.m$rest = function($block, a, b) {
|
|
422
|
+
b = Array.prototype.slice.call(arguments, 2);
|
|
423
|
+
return nil;
|
|
424
|
+
};
|
|
425
|
+
</pre>
|
|
426
|
+
|
|
427
|
+
<h2 id="change_log">Change Log</h2>
|
|
428
|
+
|
|
429
|
+
<h3>0.3.15</h3>
|
|
430
|
+
|
|
431
|
+
<p>Initial Release.</p>
|
|
432
|
+
</div>
|
|
433
|
+
</body>
|
|
434
|
+
</html>
|