opal 0.3.19 → 0.3.20
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 +3 -1
- data/Gemfile +3 -2
- data/README.md +304 -48
- data/Rakefile +1 -2
- data/core/alpha.rb +2 -1
- data/core/array.rb +92 -96
- data/core/basic_object.rb +1 -10
- data/core/boolean.rb +6 -18
- data/core/class.rb +9 -10
- data/core/comparable.rb +1 -1
- data/core/enumerable.rb +11 -11
- data/core/enumerator.rb +2 -10
- data/core/error.rb +16 -31
- data/core/hash.rb +32 -36
- data/core/json.rb +50 -0
- data/core/kernel.rb +48 -57
- data/core/load_order +3 -5
- data/core/module.rb +37 -35
- data/core/nil_class.rb +4 -0
- data/core/numeric.rb +10 -30
- data/core/proc.rb +1 -1
- data/core/range.rb +3 -4
- data/core/regexp.rb +21 -6
- data/core/runtime.js +278 -370
- data/core/string.rb +21 -37
- data/core/struct.rb +11 -3
- data/core/time.rb +44 -37
- data/lib/opal.rb +3 -3
- data/lib/opal/builder.rb +48 -27
- data/lib/opal/builder_task.rb +3 -20
- data/lib/opal/grammar.rb +18 -13
- data/lib/opal/grammar.y +7 -4
- data/lib/opal/parser.rb +290 -199
- data/lib/opal/scope.rb +187 -176
- data/lib/opal/version.rb +1 -1
- data/test/core/kernel/define_singleton_method_spec.rb +21 -0
- data/test/core/time/at_spec.rb +7 -0
- data/test/core/time/day_spec.rb +5 -0
- data/test/core/time/friday_spec.rb +9 -0
- data/test/core/time/hour_spec.rb +5 -0
- data/test/core/time/min_spec.rb +5 -0
- data/test/core/time/monday_spec.rb +9 -0
- data/test/core/time/month_spec.rb +5 -0
- data/test/core/time/now_spec.rb +5 -0
- data/test/core/time/saturday_spec.rb +9 -0
- data/test/index.html +2 -1
- data/test/language/singleton_class_spec.rb +0 -16
- data/test/opal/array/to_json_spec.rb +7 -0
- data/test/opal/boolean/singleton_class_spec.rb +9 -0
- data/test/opal/boolean/to_json_spec.rb +9 -0
- data/test/opal/hash/to_json_spec.rb +9 -0
- data/test/opal/json/parse_spec.rb +31 -0
- data/test/opal/kernel/to_json_spec.rb +5 -0
- data/test/opal/nil/to_json_spec.rb +5 -0
- data/test/opal/numeric/to_json_spec.rb +6 -0
- data/test/opal/runtime/call_spec.rb +16 -0
- data/test/opal/runtime/defined_spec.rb +11 -0
- data/test/opal/runtime/super_spec.rb +16 -0
- data/test/opal/string/to_json_spec.rb +6 -0
- data/test/spec_helper.rb +1 -3
- metadata +48 -15
- data/core/dir.rb +0 -89
- data/core/file.rb +0 -85
- data/core/match_data.rb +0 -35
- data/core/rational.rb +0 -16
- data/test/core/file/expand_path_spec.rb +0 -20
    
        data/.gitignore
    CHANGED
    
    
    
        data/Gemfile
    CHANGED
    
    
    
        data/README.md
    CHANGED
    
    | @@ -19,7 +19,7 @@ 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.20](http://opalrb.org/opal.js) _(14.3kb Minified And Gzipped)_
         | 
| 23 23 |  | 
| 24 24 | 
             
            ## Installation
         | 
| 25 25 |  | 
| @@ -41,18 +41,22 @@ method which returns a string of javascript code: | |
| 41 41 | 
             
            ```ruby
         | 
| 42 42 | 
             
            require 'opal'
         | 
| 43 43 |  | 
| 44 | 
            -
            Opal.parse(" | 
| 44 | 
            +
            Opal.parse("puts 'hello world'")
         | 
| 45 45 | 
             
            ```
         | 
| 46 46 |  | 
| 47 | 
            -
            This will return a string of javascript | 
| 47 | 
            +
            This will return a string of javascript:
         | 
| 48 48 |  | 
| 49 49 | 
             
            ```javascript
         | 
| 50 50 | 
             
            (function() {
         | 
| 51 | 
            -
               | 
| 52 | 
            -
             | 
| 51 | 
            +
              var self = Opal.top;
         | 
| 52 | 
            +
              self.$puts('hello world');
         | 
| 53 | 
            +
            })();
         | 
| 53 54 | 
             
            ```
         | 
| 54 55 |  | 
| 55 | 
            -
            This can then be written to a file and run in any browser.
         | 
| 56 | 
            +
            This can then be written to a file and run in any browser. `Opal` is a
         | 
| 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.
         | 
| 56 60 |  | 
| 57 61 | 
             
            ### Creating a rake task
         | 
| 58 62 |  | 
| @@ -98,7 +102,7 @@ opal runtime needs to be loaded first (you can download that above). | |
| 98 102 |  | 
| 99 103 | 
             
            When using `Opal.parse()` as above, the generated code will be run
         | 
| 100 104 | 
             
            as soon as the page loads. Open the browsers console and you should
         | 
| 101 | 
            -
            see the  | 
| 105 | 
            +
            see the message printed to the console.
         | 
| 102 106 |  | 
| 103 107 | 
             
            ## Builder and Dependency Builder
         | 
| 104 108 |  | 
| @@ -114,7 +118,7 @@ require 'opal' | |
| 114 118 |  | 
| 115 119 | 
             
            Opal::BuilderTask.new do |t|
         | 
| 116 120 | 
             
              t.name         = 'my-first-app'
         | 
| 117 | 
            -
              t.dependencies = ['opal- | 
| 121 | 
            +
              t.dependencies = ['opal-spec']
         | 
| 118 122 | 
             
              t.files        = ['app.rb']
         | 
| 119 123 | 
             
            end
         | 
| 120 124 | 
             
            ```
         | 
| @@ -124,16 +128,16 @@ dependencies. | |
| 124 128 |  | 
| 125 129 | 
             
            ### Building dependencies
         | 
| 126 130 |  | 
| 127 | 
            -
            To build the opal runtime `opal.js`, as well as `opal- | 
| 131 | 
            +
            To build the opal runtime `opal.js`, as well as `opal-spec` into
         | 
| 128 132 | 
             
            `build/`, run the simple rake task:
         | 
| 129 133 |  | 
| 130 134 | 
             
            ```ruby
         | 
| 131 135 | 
             
            rake dependencies
         | 
| 132 136 | 
             
            ```
         | 
| 133 137 |  | 
| 134 | 
            -
            This will try and find the `opal- | 
| 135 | 
            -
            install globally with `gem install opal- | 
| 136 | 
            -
            Gemfile as `gem "opal- | 
| 138 | 
            +
            This will try and find the `opal-spec` gem installed, so either
         | 
| 139 | 
            +
            install globally with `gem install opal-spec`, or add it to your
         | 
| 140 | 
            +
            Gemfile as `gem "opal-spec"` and run `bundle install`.
         | 
| 137 141 |  | 
| 138 142 | 
             
            ### Building app
         | 
| 139 143 |  | 
| @@ -158,28 +162,12 @@ You should now be able to run the built app using a standard HTML page. | |
| 158 162 | 
             
            </head>
         | 
| 159 163 | 
             
            <body>
         | 
| 160 164 | 
             
              <script src="build/opal.js"></script>
         | 
| 161 | 
            -
              <script src="build/opal- | 
| 165 | 
            +
              <script src="build/opal-spec.js"></script>
         | 
| 162 166 | 
             
              <script src="build/my-first-app.js"></script>
         | 
| 163 167 | 
             
            </body>
         | 
| 164 168 | 
             
            </html>
         | 
| 165 169 | 
             
            ```
         | 
| 166 170 |  | 
| 167 | 
            -
            ### Main file
         | 
| 168 | 
            -
             | 
| 169 | 
            -
            When using the `BuilderTask`, the files generated will not be run
         | 
| 170 | 
            -
            automatically on page load. The files are registered so they can be
         | 
| 171 | 
            -
            loaded using `require()`. Builder is clever enough though that it will,
         | 
| 172 | 
            -
            by default, automatically require the first file in the app to be
         | 
| 173 | 
            -
            loaded. This will appear at the bottom of `my-first-app.js`:
         | 
| 174 | 
            -
             | 
| 175 | 
            -
            ```javascript
         | 
| 176 | 
            -
            Opal.define('app', function() {
         | 
| 177 | 
            -
              // app.rb code
         | 
| 178 | 
            -
            });
         | 
| 179 | 
            -
             | 
| 180 | 
            -
            Opal.require('app');
         | 
| 181 | 
            -
            ```
         | 
| 182 | 
            -
             | 
| 183 171 | 
             
            ## Features And Implementation
         | 
| 184 172 |  | 
| 185 173 | 
             
            Opal is a source-to-source compiler, so there is no VM as such and the
         | 
| @@ -274,6 +262,49 @@ range instances. | |
| 274 262 | 
             
            3...7       # => __range(3, 7, false)
         | 
| 275 263 | 
             
            ```
         | 
| 276 264 |  | 
| 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 | 
            +
             | 
| 277 308 | 
             
            ### Methods
         | 
| 278 309 |  | 
| 279 310 | 
             
            A ruby method is just compiled directly into a function definition.
         | 
| @@ -352,12 +383,12 @@ def to_s | |
| 352 383 | 
             
            end
         | 
| 353 384 | 
             
            ```
         | 
| 354 385 |  | 
| 355 | 
            -
            This would generate the following javascript. (` | 
| 356 | 
            -
             | 
| 357 | 
            -
             | 
| 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).
         | 
| 358 389 |  | 
| 359 390 | 
             
            ```javascript
         | 
| 360 | 
            -
             | 
| 391 | 
            +
            Array_prototype.$to_s = function() {
         | 
| 361 392 | 
             
              return this.$inspect();
         | 
| 362 393 | 
             
            };
         | 
| 363 394 | 
             
            ```
         | 
| @@ -384,16 +415,16 @@ end | |
| 384 415 | 
             
            The generated code reads as expected:
         | 
| 385 416 |  | 
| 386 417 | 
             
            ```javascript
         | 
| 387 | 
            -
             | 
| 418 | 
            +
            Array_prototype.$norm = function(a, b, c) {
         | 
| 388 419 | 
             
              return nil;
         | 
| 389 420 | 
             
            };
         | 
| 390 421 |  | 
| 391 | 
            -
             | 
| 422 | 
            +
            Array_prototype.$opt = function(a, b) {
         | 
| 392 423 | 
             
              if (b == null) b = 100;
         | 
| 393 424 | 
             
              return nil;
         | 
| 394 425 | 
             
            };
         | 
| 395 426 |  | 
| 396 | 
            -
             | 
| 427 | 
            +
            Array_prototype.$rest = function(a, b) {
         | 
| 397 428 | 
             
              b = __slice.call(arguments, 1);
         | 
| 398 429 | 
             
              return nil;
         | 
| 399 430 | 
             
            };
         | 
| @@ -404,6 +435,144 @@ the correct number of arguments get passed to a function. This can be | |
| 404 435 | 
             
            enabled in debug mode, but is not included in production builds as it
         | 
| 405 436 | 
             
            adds a lot of overhead to **every** method call.
         | 
| 406 437 |  | 
| 438 | 
            +
            ### Logic and conditionals
         | 
| 439 | 
            +
             | 
| 440 | 
            +
            As per ruby, Opal treats only `false` and `nil` as falsy, everything
         | 
| 441 | 
            +
            else is a truthy value including `""`, `0` and `[]`. This differs from
         | 
| 442 | 
            +
            javascript as these values are also treated as false.
         | 
| 443 | 
            +
             | 
| 444 | 
            +
            For this reason, most truthy tests must check if values are `false` or
         | 
| 445 | 
            +
            `nil`.
         | 
| 446 | 
            +
             | 
| 447 | 
            +
            Taking the following test:
         | 
| 448 | 
            +
             | 
| 449 | 
            +
            ```javascript
         | 
| 450 | 
            +
            val = 42
         | 
| 451 | 
            +
             | 
| 452 | 
            +
            if val
         | 
| 453 | 
            +
              return 3.142;
         | 
| 454 | 
            +
            end
         | 
| 455 | 
            +
            ```
         | 
| 456 | 
            +
             | 
| 457 | 
            +
            This would be compiled into:
         | 
| 458 | 
            +
             | 
| 459 | 
            +
            ```ruby
         | 
| 460 | 
            +
            val = 42;
         | 
| 461 | 
            +
             | 
| 462 | 
            +
            if (val !== false && val !== nil) {
         | 
| 463 | 
            +
              return 3.142;
         | 
| 464 | 
            +
            }
         | 
| 465 | 
            +
            ```
         | 
| 466 | 
            +
             | 
| 467 | 
            +
            This makes the generated truthy tests (`if` statements, `and` checks and
         | 
| 468 | 
            +
            `or` statements) a litle more verbose in the generated code.
         | 
| 469 | 
            +
             | 
| 470 | 
            +
            ### Instance variables
         | 
| 471 | 
            +
             | 
| 472 | 
            +
            Instance variables in Opal work just as expected. When ivars are set or
         | 
| 473 | 
            +
            retrieved on an object, they are set natively without the `@` prefix.
         | 
| 474 | 
            +
            This allows real javascript identifiers to be used which is more
         | 
| 475 | 
            +
            efficient then accessing variables by string name.
         | 
| 476 | 
            +
             | 
| 477 | 
            +
            ```ruby
         | 
| 478 | 
            +
            @foo = 200
         | 
| 479 | 
            +
            @foo  # => 200
         | 
| 480 | 
            +
             | 
| 481 | 
            +
            @bar  # => nil
         | 
| 482 | 
            +
            ```
         | 
| 483 | 
            +
             | 
| 484 | 
            +
            This gets compiled into:
         | 
| 485 | 
            +
             | 
| 486 | 
            +
            ```javascript
         | 
| 487 | 
            +
            this.foo = 200;
         | 
| 488 | 
            +
            this.foo;   // => 200
         | 
| 489 | 
            +
             | 
| 490 | 
            +
            this.bar;   // => nil
         | 
| 491 | 
            +
            ```
         | 
| 492 | 
            +
             | 
| 493 | 
            +
            The only point of warning is that when variables are used for the
         | 
| 494 | 
            +
            first time in ruby, they default to `nil`. In javascript, they default
         | 
| 495 | 
            +
            to `undefined`/`null`.
         | 
| 496 | 
            +
             | 
| 497 | 
            +
            To keep things working in opal, ivars must be preset to `nil` before
         | 
| 498 | 
            +
            they can be used. In the top scope and other corner cases, this needs
         | 
| 499 | 
            +
            to be done on a per scope basis, which can add overhead.
         | 
| 500 | 
            +
             | 
| 501 | 
            +
            To improve performance, once a class body is compiled, all ivars used
         | 
| 502 | 
            +
            within methods in that class are preset on the prototype of the class
         | 
| 503 | 
            +
            to be `nil`. This means that all known ivars are already set to nil,
         | 
| 504 | 
            +
            and this is done just once during the lifespan of the app.
         | 
| 505 | 
            +
             | 
| 506 | 
            +
            ```ruby
         | 
| 507 | 
            +
            class Foo
         | 
| 508 | 
            +
              def bar
         | 
| 509 | 
            +
                @lol
         | 
| 510 | 
            +
              end
         | 
| 511 | 
            +
             | 
| 512 | 
            +
              def woosh
         | 
| 513 | 
            +
                @kapow
         | 
| 514 | 
            +
              end
         | 
| 515 | 
            +
            end
         | 
| 516 | 
            +
            ```
         | 
| 517 | 
            +
             | 
| 518 | 
            +
            This example gets compiled into something similar to:
         | 
| 519 | 
            +
             | 
| 520 | 
            +
            ```javascript
         | 
| 521 | 
            +
            (function() {
         | 
| 522 | 
            +
              function Foo(){}
         | 
| 523 | 
            +
              // ...
         | 
| 524 | 
            +
             | 
| 525 | 
            +
              Foo.prototype.lol = Foo.prototype.woosh = nil;
         | 
| 526 | 
            +
             | 
| 527 | 
            +
              Foo.prototype.$bar = function() {
         | 
| 528 | 
            +
                return this.lol;
         | 
| 529 | 
            +
              };
         | 
| 530 | 
            +
             | 
| 531 | 
            +
              // etc ...
         | 
| 532 | 
            +
            })()
         | 
| 533 | 
            +
            ```
         | 
| 534 | 
            +
             | 
| 535 | 
            +
            ### Interacting with javascript
         | 
| 536 | 
            +
             | 
| 537 | 
            +
            Opal tries to interact as cleanly with javascript and its api as much
         | 
| 538 | 
            +
            as possible. Ruby arrays, strings, numbers, regexps, blocks and booleans
         | 
| 539 | 
            +
            are just javascript native equivalents. The only boxed core features are
         | 
| 540 | 
            +
            hashes and nil.
         | 
| 541 | 
            +
             | 
| 542 | 
            +
            As most of the corelib deals with these low level details, opal provides
         | 
| 543 | 
            +
            a special syntax for inlining javascript code. This is done with
         | 
| 544 | 
            +
            x-strings or "backticks", as their ruby use has no useful translation
         | 
| 545 | 
            +
            in the browser.
         | 
| 546 | 
            +
             | 
| 547 | 
            +
            ```ruby
         | 
| 548 | 
            +
            `window.title`
         | 
| 549 | 
            +
            # => "Opal: ruby to javascript compiler"
         | 
| 550 | 
            +
             | 
| 551 | 
            +
            %x{
         | 
| 552 | 
            +
              console.log("ruby version is:");
         | 
| 553 | 
            +
              console.log(#{ OPAL_VERSION });
         | 
| 554 | 
            +
            }
         | 
| 555 | 
            +
             | 
| 556 | 
            +
            # => ruby version is:
         | 
| 557 | 
            +
            # => 0.3.19
         | 
| 558 | 
            +
            ```
         | 
| 559 | 
            +
             | 
| 560 | 
            +
            Even interpolations are supported, as seen here.
         | 
| 561 | 
            +
             | 
| 562 | 
            +
            This feature of inlining code is used extensively, for example in
         | 
| 563 | 
            +
            Array#length:
         | 
| 564 | 
            +
             | 
| 565 | 
            +
            ```ruby
         | 
| 566 | 
            +
            class Array
         | 
| 567 | 
            +
              def length
         | 
| 568 | 
            +
                `this.length`
         | 
| 569 | 
            +
              end
         | 
| 570 | 
            +
            end
         | 
| 571 | 
            +
            ```
         | 
| 572 | 
            +
             | 
| 573 | 
            +
            X-Strings also have the ability to automatically return their value,
         | 
| 574 | 
            +
            as used by this example.
         | 
| 575 | 
            +
             | 
| 407 576 | 
             
            ### Compiled Files
         | 
| 408 577 |  | 
| 409 578 | 
             
            As described above, a compiled ruby source gets generated into a string
         | 
| @@ -411,17 +580,16 @@ of javascript code that is wrapped inside an anonymous function. This | |
| 411 580 | 
             
            looks similar to the following:
         | 
| 412 581 |  | 
| 413 582 | 
             
            ```javascript
         | 
| 414 | 
            -
            (function( | 
| 415 | 
            -
              var nil = Opal.nil,  | 
| 583 | 
            +
            (function() {
         | 
| 584 | 
            +
              var nil = Opal.nil, self = Opal.top;
         | 
| 416 585 | 
             
              // generated code
         | 
| 417 | 
            -
            }) | 
| 586 | 
            +
            })();
         | 
| 418 587 | 
             
            ```
         | 
| 419 588 |  | 
| 420 | 
            -
             | 
| 421 | 
            -
             | 
| 422 | 
            -
             | 
| 423 | 
            -
             | 
| 424 | 
            -
            from these functions as they are not used anywhere.
         | 
| 589 | 
            +
            Inside the function, `nil` is assigned to ensure a local copy is
         | 
| 590 | 
            +
            available, as well as all the helper methods used within the
         | 
| 591 | 
            +
            generated file. There is no return value from these functions as they
         | 
| 592 | 
            +
            are not used anywhere.
         | 
| 425 593 |  | 
| 426 594 | 
             
            As a complete example, assuming the following code:
         | 
| 427 595 |  | 
| @@ -432,10 +600,10 @@ puts "foo" | |
| 432 600 | 
             
            This would compile directly into:
         | 
| 433 601 |  | 
| 434 602 | 
             
            ```javascript
         | 
| 435 | 
            -
            (function( | 
| 436 | 
            -
              var nil = Opal.nil;
         | 
| 437 | 
            -
               | 
| 438 | 
            -
            }) | 
| 603 | 
            +
            (function() {
         | 
| 604 | 
            +
              var nil = Opal.nil, self = Opal.top;
         | 
| 605 | 
            +
              self.$puts("foo");
         | 
| 606 | 
            +
            })();
         | 
| 439 607 | 
             
            ```
         | 
| 440 608 |  | 
| 441 609 | 
             
            Most of the helpers are no longer present as they are not used in this
         | 
| @@ -447,12 +615,100 @@ If you write the generated code as above into a file `app.js` and add | |
| 447 615 | 
             
            that to your HTML page, then it is obvious that `"foo"` would be
         | 
| 448 616 | 
             
            written to the browser's console.
         | 
| 449 617 |  | 
| 618 | 
            +
            ### JSON
         | 
| 619 | 
            +
             | 
| 620 | 
            +
            The opal corelib includes JSON support instead of treating it as an
         | 
| 621 | 
            +
            external lib. The `JSON` module provides the usual parsing methods.
         | 
| 622 | 
            +
             | 
| 623 | 
            +
            ```ruby
         | 
| 624 | 
            +
            JSON.parse '{"a": 10, "b": [1, 2, 3], "c": null}'
         | 
| 625 | 
            +
            # => { "a" => 10, "b" => [1, 2, 3], "c" => nil }
         | 
| 626 | 
            +
            ```
         | 
| 627 | 
            +
             | 
| 628 | 
            +
            Opal expects `JSON` to be present in the browser, so older browsers
         | 
| 629 | 
            +
            may require a shim (json2.js) to work with opal. Most mobile browsers
         | 
| 630 | 
            +
            and modern desktop browsers include json support natively.
         | 
| 631 | 
            +
             | 
| 632 | 
            +
            ## Debugging and finding errors
         | 
| 633 | 
            +
             | 
| 634 | 
            +
            Because Opal does not aim to be fully compatible with ruby, there are
         | 
| 635 | 
            +
            some instances where things can break and it may not be entirely
         | 
| 636 | 
            +
            obvious what went wrong.
         | 
| 637 | 
            +
             | 
| 638 | 
            +
            ### Undefined methods
         | 
| 639 | 
            +
             | 
| 640 | 
            +
            By default, opal aims to be as fast as possible, so `method_missing` is
         | 
| 641 | 
            +
            not turned on by default. Instead, when calling a method that doesn't
         | 
| 642 | 
            +
            exist, a native error will be raised.
         | 
| 643 | 
            +
             | 
| 644 | 
            +
            ```ruby
         | 
| 645 | 
            +
            self.do_something()
         | 
| 646 | 
            +
            ```
         | 
| 647 | 
            +
             | 
| 648 | 
            +
            Might raise an error similar to:
         | 
| 649 | 
            +
             | 
| 650 | 
            +
            ```
         | 
| 651 | 
            +
            Error: 'undefined' is not a function (evaluating 'this.$do_something()')
         | 
| 652 | 
            +
            ```
         | 
| 653 | 
            +
             | 
| 654 | 
            +
            As described above, all ruby methods will have a `$` prefix which gives
         | 
| 655 | 
            +
            a good indication that it is a opal method that doesnt exist, and most
         | 
| 656 | 
            +
            js engines output the missing function name.
         | 
| 657 | 
            +
             | 
| 658 | 
            +
            ### Undefined constants
         | 
| 659 | 
            +
             | 
| 660 | 
            +
            If trying to access a constant that doesn't exist, there is no runtime
         | 
| 661 | 
            +
            error. Instead, the value of that expression is just `undefined` as
         | 
| 662 | 
            +
            constants are retrieved from objects that hold all constants in the
         | 
| 663 | 
            +
            scope. Trying to send a method to an undefined constant will therefore
         | 
| 664 | 
            +
            just raise an ugly javascript `TypeError`.
         | 
| 665 | 
            +
             | 
| 666 | 
            +
            If you are using the constant as a reference, it may not be until much
         | 
| 667 | 
            +
            later that the error occurs.
         | 
| 668 | 
            +
             | 
| 669 | 
            +
            ### Using javascript debuggers
         | 
| 670 | 
            +
             | 
| 671 | 
            +
            As opal just generates javascript, it is useful to use a native
         | 
| 672 | 
            +
            debugger to work through javascript code. To use a debugger, simply
         | 
| 673 | 
            +
            add an x-string similar to the following at the place you wish to
         | 
| 674 | 
            +
            debug:
         | 
| 675 | 
            +
             | 
| 676 | 
            +
            ```ruby
         | 
| 677 | 
            +
            # .. code
         | 
| 678 | 
            +
            `debugger`
         | 
| 679 | 
            +
            # .. more code
         | 
| 680 | 
            +
            ```
         | 
| 681 | 
            +
            The x-strings just pass the debugger statement straight through to the
         | 
| 682 | 
            +
            javascript output.
         | 
| 683 | 
            +
             | 
| 684 | 
            +
            Inside methods and blocks, the current `self` value is always the
         | 
| 685 | 
            +
            native `this` value. You will not see `self` inside debuggers as it is
         | 
| 686 | 
            +
            never used to refer to the actual ruby self value.
         | 
| 687 | 
            +
             | 
| 688 | 
            +
            All local variables and method/block arguments also keep their ruby
         | 
| 689 | 
            +
            names except in the rare cases when the name is reserved in javascript.
         | 
| 690 | 
            +
            In these cases, a `$` suffix is added to the name (e.g. `try` =>
         | 
| 691 | 
            +
            `try$`).
         | 
| 692 | 
            +
             | 
| 450 693 | 
             
            ## License
         | 
| 451 694 |  | 
| 452 695 | 
             
            Opal is released under the MIT license.
         | 
| 453 696 |  | 
| 454 697 | 
             
            ## Change Log
         | 
| 455 698 |  | 
| 699 | 
            +
            **0.3.20** _(23 June 2012)_
         | 
| 700 | 
            +
             | 
| 701 | 
            +
            * Merge JSON into core. JSON module and various #to_json methods are
         | 
| 702 | 
            +
              now included as part of corelib
         | 
| 703 | 
            +
            * Make `Time` class bridge to native `Date` constructor
         | 
| 704 | 
            +
            * Use named functions as class constuctors to make debugging easier
         | 
| 705 | 
            +
            * Classes are now real functions with prototypes. Bridged classes are
         | 
| 706 | 
            +
              now directly corresponding to the ruby class (e.g. Array === Opal.Array)
         | 
| 707 | 
            +
            * Set ivars used inside methods in class to `nil` inside class definition
         | 
| 708 | 
            +
              to avoid doing it everytime method is called
         | 
| 709 | 
            +
            * Add debug comments to output for def, class and module stating the file
         | 
| 710 | 
            +
              and line number the given code was generated from
         | 
| 711 | 
            +
             | 
| 456 712 | 
             
            **0.3.19** _(30 May 2012)_
         | 
| 457 713 |  | 
| 458 714 | 
             
            * Add BasicObject as the root class
         |