opal 0.8.1 → 0.9.0.beta1
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.
- checksums.yaml +4 -4
 - data/.gitignore +2 -2
 - data/.gitmodules +3 -3
 - data/.jshintrc +17 -20
 - data/.travis.yml +22 -11
 - data/CHANGELOG.md +51 -1
 - data/CODE_OF_CONDUCT.md +15 -0
 - data/CONTRIBUTING.md +125 -9
 - data/Gemfile +1 -1
 - data/Guardfile +2 -2
 - data/README.md +95 -29
 - data/Rakefile +1 -1
 - data/benchmark/benchmarks +103 -0
 - data/benchmark/bm_array_flatten.rb +9 -0
 - data/benchmark/bm_array_intersection_numbers.rb +7 -0
 - data/benchmark/bm_array_intersection_objects.rb +7 -0
 - data/benchmark/bm_array_intersection_strings.rb +7 -0
 - data/benchmark/bm_array_join_ary.rb +9 -0
 - data/benchmark/bm_array_minus_numbers.rb +7 -0
 - data/benchmark/bm_array_minus_objects.rb +7 -0
 - data/benchmark/bm_array_minus_strings.rb +7 -0
 - data/benchmark/bm_array_union_numbers.rb +7 -0
 - data/benchmark/bm_array_union_objects.rb +7 -0
 - data/benchmark/bm_array_union_strings.rb +7 -0
 - data/benchmark/bm_array_uniq_bang_numbers.rb +5 -0
 - data/benchmark/bm_array_uniq_bang_objects.rb +5 -0
 - data/benchmark/bm_array_uniq_bang_strings.rb +5 -0
 - data/benchmark/bm_array_uniq_numbers.rb +5 -0
 - data/benchmark/bm_array_uniq_objects.rb +5 -0
 - data/benchmark/bm_array_uniq_strings.rb +5 -0
 - data/benchmark/bm_dispatch_bind_table.rb +57 -0
 - data/benchmark/bm_dispatch_code_gen.rb +65 -0
 - data/benchmark/bm_dispatch_code_gen_if.rb +64 -0
 - data/benchmark/bm_dispatch_hardcoded.rb +44 -0
 - data/benchmark/bm_dispatch_send.rb +38 -0
 - data/benchmark/bm_dispatch_send_table.rb +57 -0
 - data/benchmark/bm_hash_assoc_object.rb +11 -0
 - data/benchmark/bm_hash_assoc_string.rb +9 -0
 - data/benchmark/bm_hash_clone_object.rb +9 -0
 - data/benchmark/bm_hash_clone_string.rb +9 -0
 - data/benchmark/bm_hash_delete_object.rb +11 -0
 - data/benchmark/bm_hash_delete_string.rb +9 -0
 - data/benchmark/bm_hash_each_key_object.rb +9 -0
 - data/benchmark/bm_hash_each_key_string.rb +9 -0
 - data/benchmark/bm_hash_each_object.rb +9 -0
 - data/benchmark/bm_hash_each_string.rb +9 -0
 - data/benchmark/bm_hash_each_value_object.rb +9 -0
 - data/benchmark/bm_hash_each_value_string.rb +9 -0
 - data/benchmark/bm_hash_element_reference_object.rb +11 -0
 - data/benchmark/bm_hash_element_reference_string.rb +9 -0
 - data/benchmark/bm_hash_element_set_object.rb +5 -0
 - data/benchmark/bm_hash_element_set_string.rb +5 -0
 - data/benchmark/bm_hash_equal_value_object.rb +14 -0
 - data/benchmark/bm_hash_equal_value_string.rb +11 -0
 - data/benchmark/bm_hash_fetch_object.rb +11 -0
 - data/benchmark/bm_hash_fetch_string.rb +9 -0
 - data/benchmark/bm_hash_flatten_object.rb +9 -0
 - data/benchmark/bm_hash_flatten_string.rb +9 -0
 - data/benchmark/bm_hash_has_key_object.rb +11 -0
 - data/benchmark/bm_hash_has_key_string.rb +9 -0
 - data/benchmark/bm_hash_has_value_object.rb +9 -0
 - data/benchmark/bm_hash_has_value_string.rb +9 -0
 - data/benchmark/bm_hash_hash_object.rb +9 -0
 - data/benchmark/bm_hash_hash_string.rb +9 -0
 - data/benchmark/bm_hash_inspect_object.rb +9 -0
 - data/benchmark/bm_hash_inspect_string.rb +9 -0
 - data/benchmark/bm_hash_invert_object.rb +9 -0
 - data/benchmark/bm_hash_invert_string.rb +9 -0
 - data/benchmark/bm_hash_keep_if_object.rb +9 -0
 - data/benchmark/bm_hash_keep_if_string.rb +9 -0
 - data/benchmark/bm_hash_key_object.rb +9 -0
 - data/benchmark/bm_hash_key_string.rb +9 -0
 - data/benchmark/bm_hash_keys_object.rb +9 -0
 - data/benchmark/bm_hash_keys_string.rb +9 -0
 - data/benchmark/bm_hash_literal_mixed_large.rb +3 -0
 - data/benchmark/bm_hash_literal_mixed_small.rb +3 -0
 - data/benchmark/bm_hash_literal_object_large.rb +4 -0
 - data/benchmark/bm_hash_literal_object_small.rb +3 -0
 - data/benchmark/bm_hash_literal_string_large.rb +4 -0
 - data/benchmark/bm_hash_literal_string_small.rb +3 -0
 - data/benchmark/bm_hash_merge_object.rb +22 -0
 - data/benchmark/bm_hash_merge_string.rb +18 -0
 - data/benchmark/bm_hash_rassoc_object.rb +9 -0
 - data/benchmark/bm_hash_rassoc_string.rb +9 -0
 - data/benchmark/bm_hash_rehash_object.rb +9 -0
 - data/benchmark/bm_hash_rehash_string.rb +9 -0
 - data/benchmark/bm_hash_reject_bang_object.rb +9 -0
 - data/benchmark/bm_hash_reject_bang_string.rb +9 -0
 - data/benchmark/bm_hash_reject_object.rb +9 -0
 - data/benchmark/bm_hash_reject_string.rb +9 -0
 - data/benchmark/bm_hash_replace_object.rb +18 -0
 - data/benchmark/bm_hash_replace_string.rb +14 -0
 - data/benchmark/bm_hash_select_bang_object.rb +9 -0
 - data/benchmark/bm_hash_select_bang_string.rb +9 -0
 - data/benchmark/bm_hash_select_object.rb +9 -0
 - data/benchmark/bm_hash_select_string.rb +9 -0
 - data/benchmark/bm_hash_shift_object.rb +10 -0
 - data/benchmark/bm_hash_shift_string.rb +10 -0
 - data/benchmark/bm_hash_to_a_object.rb +9 -0
 - data/benchmark/bm_hash_to_a_string.rb +9 -0
 - data/benchmark/bm_hash_to_h_object.rb +10 -0
 - data/benchmark/bm_hash_to_h_string.rb +10 -0
 - data/benchmark/bm_hash_values_object.rb +9 -0
 - data/benchmark/bm_hash_values_string.rb +9 -0
 - data/benchmark/run.rb +48 -0
 - data/bin/opal-mspec +1 -1
 - data/bin/opal-repl +4 -4
 - data/docs/compiled_ruby.md +214 -56
 - data/docs/configuring_gems.md +2 -2
 - data/docs/faq.md +2 -2
 - data/docs/getting_started.md +19 -2
 - data/docs/jquery.md +5 -5
 - data/docs/opal_parser.md +53 -0
 - data/docs/unsupported_features.md +2 -2
 - data/docs/upgrading.md +22 -0
 - data/docs/using_sprockets.md +15 -0
 - data/examples/rack/config.ru +13 -0
 - data/examples/sinatra/config.ru +4 -5
 - data/lib/mspec/opal/runner.rb +54 -11
 - data/lib/opal.rb +1 -1
 - data/lib/opal/builder.rb +1 -1
 - data/lib/opal/builder_processors.rb +1 -1
 - data/lib/opal/cli.rb +17 -13
 - data/lib/opal/cli_options.rb +1 -1
 - data/lib/opal/compiler.rb +12 -0
 - data/lib/opal/config.rb +4 -0
 - data/lib/opal/nodes/arglist.rb +5 -7
 - data/lib/opal/nodes/call.rb +6 -1
 - data/lib/opal/nodes/call_special.rb +74 -0
 - data/lib/opal/nodes/def.rb +35 -28
 - data/lib/opal/nodes/definitions.rb +3 -5
 - data/lib/opal/nodes/for.rb +13 -0
 - data/lib/opal/nodes/helpers.rb +15 -1
 - data/lib/opal/nodes/if.rb +5 -5
 - data/lib/opal/nodes/iter.rb +6 -1
 - data/lib/opal/nodes/literal.rb +1 -1
 - data/lib/opal/nodes/logic.rb +2 -2
 - data/lib/opal/nodes/masgn.rb +1 -2
 - data/lib/opal/nodes/module.rb +2 -1
 - data/lib/opal/nodes/rescue.rb +10 -1
 - data/lib/opal/nodes/scope.rb +8 -2
 - data/lib/opal/nodes/singleton_class.rb +1 -1
 - data/lib/opal/nodes/top.rb +11 -0
 - data/lib/opal/nodes/variables.rb +4 -4
 - data/lib/opal/parser.rb +21 -3
 - data/lib/opal/parser/grammar.rb +3115 -2961
 - data/lib/opal/parser/grammar.y +29 -6
 - data/lib/opal/parser/lexer.rb +18 -8
 - data/lib/opal/sprockets.rb +85 -0
 - data/lib/opal/sprockets/processor.rb +11 -35
 - data/lib/opal/sprockets/server.rb +3 -15
 - data/lib/opal/version.rb +2 -2
 - data/opal.gemspec +4 -4
 - data/opal/README.md +9 -0
 - data/opal/corelib/array.rb +433 -181
 - data/opal/corelib/basic_object.rb +48 -4
 - data/opal/corelib/boolean.rb +15 -6
 - data/opal/corelib/class.rb +6 -5
 - data/opal/corelib/comparable.rb +12 -0
 - data/opal/corelib/complex.rb +282 -0
 - data/opal/corelib/constants.rb +9 -0
 - data/opal/corelib/enumerable.rb +83 -34
 - data/opal/corelib/enumerator.rb +3 -1
 - data/opal/corelib/error.rb +49 -10
 - data/opal/corelib/file.rb +1 -0
 - data/opal/corelib/hash.rb +353 -577
 - data/opal/corelib/helpers.rb +20 -0
 - data/opal/corelib/kernel.rb +114 -59
 - data/opal/corelib/math.rb +470 -0
 - data/opal/corelib/method.rb +11 -2
 - data/opal/corelib/module.rb +96 -96
 - data/opal/corelib/{nil_class.rb → nil.rb} +20 -1
 - data/opal/corelib/number.rb +751 -0
 - data/opal/corelib/numeric.rb +77 -437
 - data/opal/corelib/proc.rb +81 -1
 - data/opal/corelib/process.rb +27 -0
 - data/opal/corelib/rational.rb +358 -0
 - data/opal/corelib/regexp.rb +156 -27
 - data/opal/corelib/runtime.js +724 -335
 - data/opal/corelib/string.rb +93 -104
 - data/opal/corelib/string/encoding.rb +177 -0
 - data/opal/corelib/string/inheritance.rb +2 -0
 - data/opal/corelib/struct.rb +105 -18
 - data/opal/corelib/time.rb +267 -146
 - data/opal/corelib/unsupported.rb +216 -0
 - data/opal/corelib/variables.rb +0 -6
 - data/opal/opal.rb +8 -22
 - data/opal/opal/base.rb +9 -0
 - data/opal/opal/mini.rb +17 -0
 - data/spec/README.md +1 -1
 - data/spec/filters/bugs/array.rb +38 -136
 - data/spec/filters/bugs/{basic_object.rb → basicobject.rb} +14 -15
 - data/spec/filters/bugs/class.rb +6 -12
 - data/spec/filters/bugs/complex.rb +3 -0
 - data/spec/filters/bugs/date.rb +162 -10
 - data/spec/filters/bugs/enumerable.rb +31 -58
 - data/spec/filters/bugs/enumerator.rb +42 -0
 - data/spec/filters/bugs/exception.rb +66 -10
 - data/spec/filters/bugs/float.rb +17 -0
 - data/spec/filters/bugs/hash.rb +11 -97
 - data/spec/filters/bugs/inheritance.rb +5 -0
 - data/spec/filters/bugs/integer.rb +28 -0
 - data/spec/filters/bugs/kernel.rb +304 -12
 - data/spec/filters/bugs/language.rb +133 -399
 - data/spec/filters/bugs/language_opal.rb +88 -0
 - data/spec/filters/bugs/module.rb +203 -62
 - data/spec/filters/bugs/numeric.rb +32 -0
 - data/spec/filters/bugs/proc.rb +39 -0
 - data/spec/filters/bugs/range.rb +148 -0
 - data/spec/filters/bugs/regexp.rb +168 -0
 - data/spec/filters/bugs/set.rb +46 -3
 - data/spec/filters/bugs/singleton.rb +1 -2
 - data/spec/filters/bugs/string.rb +59 -90
 - data/spec/filters/bugs/strscan.rb +80 -0
 - data/spec/filters/bugs/struct.rb +10 -20
 - data/spec/filters/bugs/time.rb +17 -184
 - data/spec/filters/bugs/unboundmethod.rb +22 -0
 - data/spec/filters/unsupported/array.rb +163 -0
 - data/spec/filters/unsupported/basicobject.rb +14 -0
 - data/spec/filters/unsupported/bignum.rb +46 -0
 - data/spec/filters/unsupported/class.rb +4 -0
 - data/spec/filters/unsupported/delegator.rb +5 -0
 - data/spec/filters/unsupported/enumerable.rb +11 -0
 - data/spec/filters/unsupported/enumerator.rb +8 -9
 - data/spec/filters/unsupported/fixnum.rb +14 -0
 - data/spec/filters/unsupported/float.rb +41 -7
 - data/spec/filters/unsupported/freeze.rb +45 -0
 - data/spec/filters/unsupported/hash.rb +50 -0
 - data/spec/filters/unsupported/integer.rb +3 -0
 - data/spec/filters/unsupported/kernel.rb +31 -0
 - data/spec/filters/unsupported/language.rb +17 -0
 - data/spec/filters/unsupported/matchdata.rb +30 -0
 - data/spec/filters/unsupported/math.rb +3 -0
 - data/spec/filters/unsupported/module.rb +5 -3
 - data/spec/filters/unsupported/pathname.rb +3 -0
 - data/spec/filters/unsupported/privacy.rb +136 -0
 - data/spec/filters/unsupported/proc.rb +3 -0
 - data/spec/filters/unsupported/regexp.rb +59 -0
 - data/spec/filters/unsupported/set.rb +4 -0
 - data/spec/filters/unsupported/{marshal.rb → singleton.rb} +4 -2
 - data/spec/filters/unsupported/{mutable_strings.rb → string.rb} +456 -336
 - data/spec/filters/unsupported/struct.rb +3 -0
 - data/spec/filters/unsupported/symbol.rb +5 -0
 - data/spec/filters/unsupported/taint.rb +16 -0
 - data/spec/filters/unsupported/thread.rb +5 -0
 - data/spec/filters/unsupported/time.rb +197 -16
 - data/spec/lib/cli_spec.rb +14 -4
 - data/spec/lib/compiler_spec.rb +9 -1
 - data/spec/lib/parser/call_spec.rb +18 -0
 - data/spec/lib/parser/not_spec.rb +2 -8
 - data/spec/lib/sprockets_spec.rb +24 -0
 - data/spec/opal/core/array/intersection_spec.rb +38 -0
 - data/spec/opal/core/array/minus_spec.rb +38 -0
 - data/spec/opal/core/array/union_spec.rb +38 -0
 - data/spec/opal/core/array/uniq_spec.rb +49 -0
 - data/spec/opal/core/exception_spec.rb +7 -0
 - data/spec/opal/core/fixtures/require_tree_with_dot/file 1.rb +1 -0
 - data/spec/opal/core/fixtures/require_tree_with_dot/file 2.rb +1 -0
 - data/spec/opal/core/fixtures/require_tree_with_dot/file 3.rb +1 -0
 - data/spec/opal/core/fixtures/require_tree_with_dot/index.rb +3 -0
 - data/spec/opal/core/hash/internals_spec.rb +332 -0
 - data/spec/opal/core/helpers_spec.rb +14 -0
 - data/spec/opal/core/kernel/freeze_spec.rb +1 -1
 - data/spec/opal/core/kernel/raise_spec.rb +13 -0
 - data/spec/opal/core/kernel/require_tree_spec.rb +9 -0
 - data/spec/opal/core/language/class_spec.rb +55 -0
 - data/spec/opal/core/language/fixtures/send.rb +1 -0
 - data/spec/opal/core/language/keyword_arguments_spec.rb +11 -0
 - data/spec/opal/core/language/send_spec.rb +5 -0
 - data/spec/opal/core/method/to_proc_spec.rb +28 -0
 - data/spec/opal/core/module/name_spec.rb +0 -17
 - data/spec/opal/core/runtime/bridged_classes_spec.rb +2 -2
 - data/spec/opal/core/runtime/eval_spec.rb +1 -1
 - data/spec/opal/core/runtime/method_missing_spec.rb +6 -0
 - data/spec/opal/core/runtime_spec.rb +51 -0
 - data/spec/opal/stdlib/js_spec.rb +66 -0
 - data/spec/opal/stdlib/native/hash_spec.rb +36 -0
 - data/spec/rubyspecs +152 -273
 - data/spec/spec_helper.rb +10 -11
 - data/stdlib/base64.rb +9 -9
 - data/stdlib/benchmark.rb +551 -4
 - data/stdlib/console.rb +94 -0
 - data/stdlib/date.rb +1 -1
 - data/stdlib/encoding.rb +1 -170
 - data/stdlib/js.rb +56 -0
 - data/stdlib/json.rb +9 -14
 - data/stdlib/math.rb +1 -370
 - data/stdlib/native.rb +133 -63
 - data/stdlib/nodejs/file.rb +5 -0
 - data/stdlib/nodejs/fileutils.rb +13 -6
 - data/stdlib/nodejs/node_modules/js-yaml/node_modules/argparse/README.md +1 -1
 - data/stdlib/opal-parser.rb +1 -2
 - data/stdlib/ostruct.rb +65 -6
 - data/stdlib/pp.rb +2 -4
 - data/stdlib/rbconfig.rb +1 -3
 - data/stdlib/strscan.rb +164 -28
 - data/tasks/benchmarking.rake +88 -0
 - data/tasks/testing.rake +181 -55
 - data/{lib/mspec/opal/special_calls.rb → tasks/testing/mspec_special_calls.rb} +1 -1
 - data/{lib/mspec/opal/sprockets.js → tasks/testing/phantomjs1-sprockets.js} +17 -6
 - data/test/opal/test_keyword.rb +590 -0
 - data/vendored-minitest/minitest.rb +2 -2
 - data/vendored-minitest/test/unit.rb +5 -0
 - metadata +229 -62
 - data/benchmarks/operators.rb +0 -11
 - data/benchmarks/prova.js.rb +0 -13
 - data/docs/libraries.md +0 -36
 - data/lib/mspec/opal/new.html.erb +0 -1
 - data/lib/mspec/opal/rake_task.rb +0 -248
 - data/opal/corelib/match_data.rb +0 -128
 - data/spec/filters/bugs/math.rb +0 -95
 - data/spec/filters/bugs/nil.rb +0 -7
 - data/spec/filters/bugs/opal.rb +0 -9
 - data/spec/filters/bugs/regular_expressions.rb +0 -41
 - data/spec/filters/bugs/stringscanner.rb +0 -33
 - data/spec/filters/unsupported/encoding.rb +0 -102
 - data/spec/filters/unsupported/frozen.rb +0 -92
 - data/spec/filters/unsupported/hash_compare_by_identity.rb +0 -16
 - data/spec/filters/unsupported/integer_size.rb +0 -59
 - data/spec/filters/unsupported/method_added.rb +0 -10
 - data/spec/filters/unsupported/private_constants.rb +0 -30
 - data/spec/filters/unsupported/private_methods.rb +0 -55
 - data/spec/filters/unsupported/random.rb +0 -4
 - data/spec/filters/unsupported/rational_numbers.rb +0 -4
 - data/spec/filters/unsupported/regular_expressions.rb +0 -137
 - data/spec/filters/unsupported/ruby_exe.rb +0 -5
 - data/spec/filters/unsupported/symbols.rb +0 -17
 - data/spec/filters/unsupported/tainted.rb +0 -180
 - data/spec/filters/unsupported/trusted.rb +0 -88
 - data/stdlib/process.rb +0 -10
 - data/tasks/documenting.rake +0 -37
 
    
        data/benchmark/run.rb
    ADDED
    
    | 
         @@ -0,0 +1,48 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            if RUBY_ENGINE == 'opal'
         
     | 
| 
      
 2 
     | 
    
         
            +
              require 'opal/compiler'
         
     | 
| 
      
 3 
     | 
    
         
            +
              require 'nodejs'
         
     | 
| 
      
 4 
     | 
    
         
            +
            end
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            BEST_OF_N = Integer(ENV['BEST_OF_N']) rescue 1
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            require 'benchmark'
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            files = ARGV
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            if files.empty?
         
     | 
| 
      
 13 
     | 
    
         
            +
              files = File.read('benchmark/benchmarks').lines.map(&:strip).reject do |line|
         
     | 
| 
      
 14 
     | 
    
         
            +
                line.empty? || line.start_with?('#')
         
     | 
| 
      
 15 
     | 
    
         
            +
              end
         
     | 
| 
      
 16 
     | 
    
         
            +
            end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
            maxlen = files.max_by{|file| file.length}.length + 1
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
            total_time = 0
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
            files.each do |file|
         
     | 
| 
      
 23 
     | 
    
         
            +
              print file, " " * (maxlen - file.length)
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
              times = []
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
              if RUBY_ENGINE == 'opal'
         
     | 
| 
      
 28 
     | 
    
         
            +
                code = Opal.compile(File.read(file))
         
     | 
| 
      
 29 
     | 
    
         
            +
                BEST_OF_N.times do
         
     | 
| 
      
 30 
     | 
    
         
            +
                  times << Benchmark.measure { `eval(code)` }
         
     | 
| 
      
 31 
     | 
    
         
            +
                end
         
     | 
| 
      
 32 
     | 
    
         
            +
              else
         
     | 
| 
      
 33 
     | 
    
         
            +
                code = File.read(file)
         
     | 
| 
      
 34 
     | 
    
         
            +
                BEST_OF_N.times do
         
     | 
| 
      
 35 
     | 
    
         
            +
                  times << Benchmark.measure { eval(code) }
         
     | 
| 
      
 36 
     | 
    
         
            +
                end
         
     | 
| 
      
 37 
     | 
    
         
            +
              end
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
              time = times.min_by{|t| t.real}
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
              total_time += time.real
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
              print time.real, "\n"
         
     | 
| 
      
 44 
     | 
    
         
            +
            end
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
            bottom_line = "Executed #{ files.length } benchmark#{ 's' if files.length != 1} in #{ total_time } sec"
         
     | 
| 
      
 47 
     | 
    
         
            +
            $stderr.print "=" * bottom_line.length, "\n"
         
     | 
| 
      
 48 
     | 
    
         
            +
            $stderr.print bottom_line, "\n"
         
     | 
    
        data/bin/opal-mspec
    CHANGED
    
    | 
         @@ -7,4 +7,4 @@ pattern = %Q{MSPEC_PATTERN="{#{specs.join(',')}}"} if specs.any? 
     | 
|
| 
       7 
7 
     | 
    
         
             
            command = [pattern, 'rake mspec'].compact.join(' ')
         
     | 
| 
       8 
8 
     | 
    
         
             
            exec command
         
     | 
| 
       9 
9 
     | 
    
         | 
| 
       10 
     | 
    
         
            -
            # RUBYOPT="-rbundler/setup -rmspec/opal/special_calls" bundle exec mspec run -t opal -pspec/ 
     | 
| 
      
 10 
     | 
    
         
            +
            # RUBYOPT="-rbundler/setup -rmspec/opal/special_calls" bundle exec mspec run -t opal -pspec/rubyspec/spec_helper spec/rubyspec/core/true/*
         
     | 
    
        data/bin/opal-repl
    CHANGED
    
    | 
         @@ -14,7 +14,7 @@ module Opal 
     | 
|
| 
       14 
14 
     | 
    
         
             
                  begin
         
     | 
| 
       15 
15 
     | 
    
         
             
                    require 'v8'
         
     | 
| 
       16 
16 
     | 
    
         
             
                  rescue LoadError
         
     | 
| 
       17 
     | 
    
         
            -
                    abort 'therubyracer  
     | 
| 
      
 17 
     | 
    
         
            +
                    abort 'opal-repl depends on therubyracer gem, which is not currently installed'
         
     | 
| 
       18 
18 
     | 
    
         
             
                  end
         
     | 
| 
       19 
19 
     | 
    
         | 
| 
       20 
20 
     | 
    
         
             
                  @v8 = V8::Context.new
         
     | 
| 
         @@ -41,11 +41,11 @@ module Opal 
     | 
|
| 
       41 
41 
     | 
    
         | 
| 
       42 
42 
     | 
    
         
             
                  loop do
         
     | 
| 
       43 
43 
     | 
    
         
             
                    # on SIGINT lets just return from the loop..
         
     | 
| 
       44 
     | 
    
         
            -
                    trap( 
     | 
| 
      
 44 
     | 
    
         
            +
                    trap('SIGINT') { finish; return }
         
     | 
| 
       45 
45 
     | 
    
         
             
                    line = Readline.readline '>> ', true
         
     | 
| 
       46 
46 
     | 
    
         | 
| 
       47 
47 
     | 
    
         
             
                    # if we type exit, then we need to close down context
         
     | 
| 
       48 
     | 
    
         
            -
                    if line ==  
     | 
| 
      
 48 
     | 
    
         
            +
                    if line == 'exit' or line.nil?
         
     | 
| 
       49 
49 
     | 
    
         
             
                      break
         
     | 
| 
       50 
50 
     | 
    
         
             
                    end
         
     | 
| 
       51 
51 
     | 
    
         | 
| 
         @@ -57,7 +57,7 @@ module Opal 
     | 
|
| 
       57 
57 
     | 
    
         | 
| 
       58 
58 
     | 
    
         
             
                def eval_ruby(str)
         
     | 
| 
       59 
59 
     | 
    
         
             
                  code = Opal::Builder.new.build_str(str, '(irb)', :irb => true, :const_missing => true)
         
     | 
| 
       60 
     | 
    
         
            -
                  code.processed[0...-1].each{ |c| @v8.eval(c.to_s) }
         
     | 
| 
      
 60 
     | 
    
         
            +
                  code.processed[0...-1].each { |c| @v8.eval(c.to_s) }
         
     | 
| 
       61 
61 
     | 
    
         
             
                  @v8.eval "var $_result = #{code.processed.last.to_s} ($_result == null ? 'nil' : $_result.$inspect());"
         
     | 
| 
       62 
62 
     | 
    
         
             
                rescue => e
         
     | 
| 
       63 
63 
     | 
    
         
             
                  puts "#{e.message}\n\t#{e.backtrace.join("\n\t")}"
         
     | 
    
        data/docs/compiled_ruby.md
    CHANGED
    
    | 
         @@ -1,6 +1,6 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # Compiled Ruby Code
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
     | 
    
         
            -
            ## Generated  
     | 
| 
      
 3 
     | 
    
         
            +
            ## Generated JavaScript
         
     | 
| 
       4 
4 
     | 
    
         | 
| 
       5 
5 
     | 
    
         
             
            Opal is a source-to-source compiler, so there is no VM as such and the
         
     | 
| 
       6 
6 
     | 
    
         
             
            compiled code aims to be as fast and efficient as possible, mapping
         
     | 
| 
         @@ -43,11 +43,11 @@ Hello there. 
     | 
|
| 
       43 
43 
     | 
    
         
             
            EOS
         
     | 
| 
       44 
44 
     | 
    
         
             
            ```
         
     | 
| 
       45 
45 
     | 
    
         | 
| 
       46 
     | 
    
         
            -
            Ruby strings are compiled directly into  
     | 
| 
      
 46 
     | 
    
         
            +
            Ruby strings are compiled directly into JavaScript strings for
         
     | 
| 
       47 
47 
     | 
    
         
             
            performance as well as readability. This has the side effect that Opal
         
     | 
| 
       48 
48 
     | 
    
         
             
            does not support mutable strings - i.e. all strings are immutable.
         
     | 
| 
       49 
49 
     | 
    
         | 
| 
       50 
     | 
    
         
            -
            NOTE: Strings in Opal are immutable because they are compiled into regular  
     | 
| 
      
 50 
     | 
    
         
            +
            NOTE: Strings in Opal are immutable because they are compiled into regular JavaScript strings. This is done for performance reasons.
         
     | 
| 
       51 
51 
     | 
    
         | 
| 
       52 
52 
     | 
    
         
             
            For performance reasons, symbols are also compiled directly into strings.
         
     | 
| 
       53 
53 
     | 
    
         
             
            Opal supports all the symbol syntaxes, but does not have a real `Symbol`
         
     | 
| 
         @@ -55,8 +55,8 @@ class. Symbols and Strings can therefore be used interchangeably. 
     | 
|
| 
       55 
55 
     | 
    
         | 
| 
       56 
56 
     | 
    
         
             
            #### Numbers
         
     | 
| 
       57 
57 
     | 
    
         | 
| 
       58 
     | 
    
         
            -
            In Opal there is a single class for numbers; `Numeric`. To keep  
     | 
| 
       59 
     | 
    
         
            -
            as performant as possible,  
     | 
| 
      
 58 
     | 
    
         
            +
            In Opal there is a single class for numbers; `Numeric`. To keep Opal
         
     | 
| 
      
 59 
     | 
    
         
            +
            as performant as possible, Ruby numbers are mapped to native numbers.
         
     | 
| 
       60 
60 
     | 
    
         
             
            This has the side effect that all numbers must be of the same class.
         
     | 
| 
       61 
61 
     | 
    
         
             
            Most relevant methods from `Integer`, `Float` and `Numeric` are
         
     | 
| 
       62 
62 
     | 
    
         
             
            implemented on this class.
         
     | 
| 
         @@ -68,8 +68,8 @@ implemented on this class. 
     | 
|
| 
       68 
68 
     | 
    
         | 
| 
       69 
69 
     | 
    
         
             
            #### Arrays
         
     | 
| 
       70 
70 
     | 
    
         | 
| 
       71 
     | 
    
         
            -
            Ruby arrays are compiled directly into  
     | 
| 
       72 
     | 
    
         
            -
             
     | 
| 
      
 71 
     | 
    
         
            +
            Ruby arrays are compiled directly into JavaScript arrays. Special
         
     | 
| 
      
 72 
     | 
    
         
            +
            Ruby syntaxes for word arrays etc are also supported.
         
     | 
| 
       73 
73 
     | 
    
         | 
| 
       74 
74 
     | 
    
         
             
            ```ruby
         
     | 
| 
       75 
75 
     | 
    
         
             
            [1, 2, 3, 4]        # => [1, 2, 3, 4]
         
     | 
| 
         @@ -78,30 +78,30 @@ ruby syntaxes for word arrays etc are also supported. 
     | 
|
| 
       78 
78 
     | 
    
         | 
| 
       79 
79 
     | 
    
         
             
            #### Hash
         
     | 
| 
       80 
80 
     | 
    
         | 
| 
       81 
     | 
    
         
            -
            Inside a generated  
     | 
| 
       82 
     | 
    
         
            -
            creates a new hash. This is also available in  
     | 
| 
      
 81 
     | 
    
         
            +
            Inside a generated Ruby script, a function `Opal.hash` is available which
         
     | 
| 
      
 82 
     | 
    
         
            +
            creates a new hash. This is also available in JavaScript as `Opal.hash`
         
     | 
| 
       83 
83 
     | 
    
         
             
            and simply returns a new instance of the `Hash` class.
         
     | 
| 
       84 
84 
     | 
    
         | 
| 
       85 
85 
     | 
    
         
             
            ```ruby
         
     | 
| 
       86 
     | 
    
         
            -
            { :foo => 100, :baz => 700 }    # =>  
     | 
| 
       87 
     | 
    
         
            -
            { foo: 42, bar: [1, 2, 3] }     # =>  
     | 
| 
      
 86 
     | 
    
         
            +
            { :foo => 100, :baz => 700 }    # => Opal.hash("foo", 100, "baz", 700)
         
     | 
| 
      
 87 
     | 
    
         
            +
            { foo: 42, bar: [1, 2, 3] }     # => Opal.hash("foo", 42, "bar", [1, 2, 3])
         
     | 
| 
       88 
88 
     | 
    
         
             
            ```
         
     | 
| 
       89 
89 
     | 
    
         | 
| 
       90 
90 
     | 
    
         
             
            #### Range
         
     | 
| 
       91 
91 
     | 
    
         | 
| 
       92 
     | 
    
         
            -
            Similar to hash, there is a function ` 
     | 
| 
      
 92 
     | 
    
         
            +
            Similar to hash, there is a function `Opal.range` available to create
         
     | 
| 
       93 
93 
     | 
    
         
             
            range instances.
         
     | 
| 
       94 
94 
     | 
    
         | 
| 
       95 
95 
     | 
    
         
             
            ```ruby
         
     | 
| 
       96 
     | 
    
         
            -
            1..4        # =>  
     | 
| 
       97 
     | 
    
         
            -
            3...7       # =>  
     | 
| 
      
 96 
     | 
    
         
            +
            1..4        # => Opal.range(1, 4, true)
         
     | 
| 
      
 97 
     | 
    
         
            +
            3...7       # => Opal.range(3, 7, false)
         
     | 
| 
       98 
98 
     | 
    
         
             
            ```
         
     | 
| 
       99 
99 
     | 
    
         | 
| 
       100 
100 
     | 
    
         
             
            ### Logic and conditionals
         
     | 
| 
       101 
101 
     | 
    
         | 
| 
       102 
     | 
    
         
            -
            As per  
     | 
| 
      
 102 
     | 
    
         
            +
            As per Ruby, Opal treats only `false` and `nil` as falsy, everything
         
     | 
| 
       103 
103 
     | 
    
         
             
            else is a truthy value including `""`, `0` and `[]`. This differs from
         
     | 
| 
       104 
     | 
    
         
            -
             
     | 
| 
      
 104 
     | 
    
         
            +
            JavaScript as these values are also treated as false.
         
     | 
| 
       105 
105 
     | 
    
         | 
| 
       106 
106 
     | 
    
         
             
            For this reason, most truthy tests must check if values are `false` or
         
     | 
| 
       107 
107 
     | 
    
         
             
            `nil`.
         
     | 
| 
         @@ -133,7 +133,7 @@ This makes the generated truthy tests (`if` statements, `and` checks and 
     | 
|
| 
       133 
133 
     | 
    
         | 
| 
       134 
134 
     | 
    
         
             
            Instance variables in Opal work just as expected. When ivars are set or
         
     | 
| 
       135 
135 
     | 
    
         
             
            retrieved on an object, they are set natively without the `@` prefix.
         
     | 
| 
       136 
     | 
    
         
            -
            This allows real  
     | 
| 
      
 136 
     | 
    
         
            +
            This allows real JavaScript identifiers to be used which is more
         
     | 
| 
       137 
137 
     | 
    
         
             
            efficient then accessing variables by string name.
         
     | 
| 
       138 
138 
     | 
    
         | 
| 
       139 
139 
     | 
    
         
             
            ```ruby
         
     | 
| 
         @@ -152,13 +152,13 @@ this.foo;   // => 200 
     | 
|
| 
       152 
152 
     | 
    
         
             
            this.bar;   // => nil
         
     | 
| 
       153 
153 
     | 
    
         
             
            ```
         
     | 
| 
       154 
154 
     | 
    
         | 
| 
       155 
     | 
    
         
            -
            NOTE: If an instance variable uses the same name as a reserved  
     | 
| 
      
 155 
     | 
    
         
            +
            NOTE: If an instance variable uses the same name as a reserved JavaScript keyword,
         
     | 
| 
       156 
156 
     | 
    
         
             
            then the instance variable is wrapped using the object-key notation: `this['class']`.
         
     | 
| 
       157 
157 
     | 
    
         | 
| 
       158 
158 
     | 
    
         
             
            ## Compiled Files
         
     | 
| 
       159 
159 
     | 
    
         | 
| 
       160 
     | 
    
         
            -
            As described above, a compiled  
     | 
| 
       161 
     | 
    
         
            -
            of  
     | 
| 
      
 160 
     | 
    
         
            +
            As described above, a compiled Ruby source gets generated into a string
         
     | 
| 
      
 161 
     | 
    
         
            +
            of JavaScript code that is wrapped inside an anonymous function. This
         
     | 
| 
       162 
162 
     | 
    
         
             
            looks similar to the following:
         
     | 
| 
       163 
163 
     | 
    
         | 
| 
       164 
164 
     | 
    
         
             
            ```javascript
         
     | 
| 
         @@ -194,14 +194,14 @@ written to the browser's console. 
     | 
|
| 
       194 
194 
     | 
    
         | 
| 
       195 
195 
     | 
    
         
             
            ### Debugging and finding errors
         
     | 
| 
       196 
196 
     | 
    
         | 
| 
       197 
     | 
    
         
            -
            Because Opal does not aim to be fully compatible with  
     | 
| 
      
 197 
     | 
    
         
            +
            Because Opal does not aim to be fully compatible with Ruby, there are
         
     | 
| 
       198 
198 
     | 
    
         
             
            some instances where things can break and it may not be entirely
         
     | 
| 
       199 
199 
     | 
    
         
             
            obvious what went wrong.
         
     | 
| 
       200 
200 
     | 
    
         | 
| 
       201 
     | 
    
         
            -
            ### Using  
     | 
| 
      
 201 
     | 
    
         
            +
            ### Using JavaScript debuggers
         
     | 
| 
       202 
202 
     | 
    
         | 
| 
       203 
     | 
    
         
            -
            As  
     | 
| 
       204 
     | 
    
         
            -
            debugger to work through  
     | 
| 
      
 203 
     | 
    
         
            +
            As Opal just generates JavaScript, it is useful to use a native
         
     | 
| 
      
 204 
     | 
    
         
            +
            debugger to work through JavaScript code. To use a debugger, simply
         
     | 
| 
       205 
205 
     | 
    
         
             
            add an x-string similar to the following at the place you wish to
         
     | 
| 
       206 
206 
     | 
    
         
             
            debug:
         
     | 
| 
       207 
207 
     | 
    
         | 
| 
         @@ -211,31 +211,32 @@ debug: 
     | 
|
| 
       211 
211 
     | 
    
         
             
            # .. more code
         
     | 
| 
       212 
212 
     | 
    
         
             
            ```
         
     | 
| 
       213 
213 
     | 
    
         
             
            The x-strings just pass the debugger statement straight through to the
         
     | 
| 
       214 
     | 
    
         
            -
             
     | 
| 
      
 214 
     | 
    
         
            +
            JavaScript output.
         
     | 
| 
       215 
215 
     | 
    
         | 
| 
       216 
     | 
    
         
            -
            NOTE: All local variables and method/block arguments also keep their  
     | 
| 
       217 
     | 
    
         
            -
            names except in the rare cases when the name is reserved in  
     | 
| 
      
 216 
     | 
    
         
            +
            NOTE: All local variables and method/block arguments also keep their Ruby
         
     | 
| 
      
 217 
     | 
    
         
            +
            names except in the rare cases when the name is reserved in JavaScript.
         
     | 
| 
       218 
218 
     | 
    
         
             
            In these cases, a `$` suffix is added to the name
         
     | 
| 
       219 
219 
     | 
    
         
             
            (e.g. `try` → `try$`).
         
     | 
| 
       220 
220 
     | 
    
         | 
| 
       221 
     | 
    
         
            -
            ## Javascript from Ruby
         
     | 
| 
       222 
221 
     | 
    
         | 
| 
       223 
     | 
    
         
            -
             
     | 
| 
      
 222 
     | 
    
         
            +
            ## JavaScript from Ruby
         
     | 
| 
      
 223 
     | 
    
         
            +
             
     | 
| 
      
 224 
     | 
    
         
            +
            Opal tries to interact as cleanly with JavaScript and its api as much
         
     | 
| 
       224 
225 
     | 
    
         
             
            as possible. Ruby arrays, strings, numbers, regexps, blocks and booleans
         
     | 
| 
       225 
     | 
    
         
            -
            are just  
     | 
| 
      
 226 
     | 
    
         
            +
            are just JavaScript native equivalents. The only boxed core features are
         
     | 
| 
       226 
227 
     | 
    
         
             
            hashes.
         
     | 
| 
       227 
228 
     | 
    
         | 
| 
       228 
229 
     | 
    
         | 
| 
       229 
     | 
    
         
            -
            ### Inline  
     | 
| 
      
 230 
     | 
    
         
            +
            ### Inline JavaScript
         
     | 
| 
       230 
231 
     | 
    
         | 
| 
       231 
     | 
    
         
            -
            As most of the corelib deals with these low level details,  
     | 
| 
       232 
     | 
    
         
            -
            a special syntax for inlining  
     | 
| 
       233 
     | 
    
         
            -
            x-strings or "backticks", as their  
     | 
| 
      
 232 
     | 
    
         
            +
            As most of the corelib deals with these low level details, Opal provides
         
     | 
| 
      
 233 
     | 
    
         
            +
            a special syntax for inlining JavaScript code. This is done with
         
     | 
| 
      
 234 
     | 
    
         
            +
            x-strings or "backticks", as their Ruby use has no useful translation
         
     | 
| 
       234 
235 
     | 
    
         
             
            in the browser.
         
     | 
| 
       235 
236 
     | 
    
         | 
| 
       236 
237 
     | 
    
         
             
            ```ruby
         
     | 
| 
       237 
238 
     | 
    
         
             
            `window.title`
         
     | 
| 
       238 
     | 
    
         
            -
            # => "Opal: Ruby to  
     | 
| 
      
 239 
     | 
    
         
            +
            # => "Opal: Ruby to JavaScript compiler"
         
     | 
| 
       239 
240 
     | 
    
         | 
| 
       240 
241 
     | 
    
         
             
            %x{
         
     | 
| 
       241 
242 
     | 
    
         
             
              console.log("opal version is:");
         
     | 
| 
         @@ -267,7 +268,9 @@ as used by this example. 
     | 
|
| 
       267 
268 
     | 
    
         | 
| 
       268 
269 
     | 
    
         
             
            _Reposted from: [Mikamayhem](http://dev.mikamai.com/post/79398725537/using-native-javascript-objects-from-opal)_
         
     | 
| 
       269 
270 
     | 
    
         | 
| 
       270 
     | 
    
         
            -
            Opal standard lib (stdlib) includes a `Native` module,  
     | 
| 
      
 271 
     | 
    
         
            +
            Opal standard lib (stdlib) includes a `Native` module. To use it, you need to download and reference `native.js`. You can find the latest minified one from the CDN [here](http://cdn.opalrb.org/opal/current/native.min.js).
         
     | 
| 
      
 272 
     | 
    
         
            +
             
     | 
| 
      
 273 
     | 
    
         
            +
            Let's see how it works and wrap `window`:
         
     | 
| 
       271 
274 
     | 
    
         | 
| 
       272 
275 
     | 
    
         
             
            ```ruby
         
     | 
| 
       273 
276 
     | 
    
         
             
            require 'native'
         
     | 
| 
         @@ -314,34 +317,190 @@ That’s all for now, bye! 
     | 
|
| 
       314 
317 
     | 
    
         
             
            window.close!
         
     | 
| 
       315 
318 
     | 
    
         
             
            ```
         
     | 
| 
       316 
319 
     | 
    
         | 
| 
       317 
     | 
    
         
            -
             
     | 
| 
      
 320 
     | 
    
         
            +
            ### Calling JavaScript Methods
         
     | 
| 
      
 321 
     | 
    
         
            +
             
     | 
| 
      
 322 
     | 
    
         
            +
            You can make direct JavaScript method calls on using the `recv.JS.method`
         
     | 
| 
      
 323 
     | 
    
         
            +
            syntax.  For example, if you have a JavaScript object named `foo` and want to call the
         
     | 
| 
      
 324 
     | 
    
         
            +
            `bar` method on it with no arguments, with or without parentheses:
         
     | 
| 
      
 325 
     | 
    
         
            +
             
     | 
| 
      
 326 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 327 
     | 
    
         
            +
            # javascript: foo.bar()
         
     | 
| 
      
 328 
     | 
    
         
            +
            foo.JS.bar
         
     | 
| 
      
 329 
     | 
    
         
            +
            foo.JS.bar()
         
     | 
| 
      
 330 
     | 
    
         
            +
            ```
         
     | 
| 
      
 331 
     | 
    
         
            +
             
     | 
| 
      
 332 
     | 
    
         
            +
            You can call the JavaScript methods with arguments, with or without parentheses, just
         
     | 
| 
      
 333 
     | 
    
         
            +
            like Ruby methods:
         
     | 
| 
      
 334 
     | 
    
         
            +
             
     | 
| 
      
 335 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 336 
     | 
    
         
            +
            # JavaScript: foo.bar(1, "a")
         
     | 
| 
      
 337 
     | 
    
         
            +
            foo.JS.bar(1, :a)
         
     | 
| 
      
 338 
     | 
    
         
            +
            foo.JS.bar 1, :a
         
     | 
| 
      
 339 
     | 
    
         
            +
            ```
         
     | 
| 
      
 340 
     | 
    
         
            +
             
     | 
| 
      
 341 
     | 
    
         
            +
            You can call the JavaScript methods with argument splats:
         
     | 
| 
      
 342 
     | 
    
         
            +
             
     | 
| 
      
 343 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 344 
     | 
    
         
            +
            # JavaScript: ($a = foo).bar.apply($a, [1].concat([2, 3]))
         
     | 
| 
      
 345 
     | 
    
         
            +
            foo.JS.bar(1, *[2, 3])
         
     | 
| 
      
 346 
     | 
    
         
            +
            foo.JS.bar 1, *[2, 3]
         
     | 
| 
      
 347 
     | 
    
         
            +
            ```
         
     | 
| 
      
 348 
     | 
    
         
            +
             
     | 
| 
      
 349 
     | 
    
         
            +
            You can provide a block when making a JavaScript method call, and it will be
         
     | 
| 
      
 350 
     | 
    
         
            +
            converted to a JavaScript function added as the last argument to the method:
         
     | 
| 
      
 351 
     | 
    
         
            +
             
     | 
| 
      
 352 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 353 
     | 
    
         
            +
            # JavaScript:
         
     | 
| 
      
 354 
     | 
    
         
            +
            # ($a = (TMP_1 = function(arg){
         
     | 
| 
      
 355 
     | 
    
         
            +
            #     var self = TMP_1.$$s || this;
         
     | 
| 
      
 356 
     | 
    
         
            +
            #     if (arg == null) arg = nil;
         
     | 
| 
      
 357 
     | 
    
         
            +
            #     return "" + (arg.method()) + " " + (self.$baz(3))
         
     | 
| 
      
 358 
     | 
    
         
            +
            #    },
         
     | 
| 
      
 359 
     | 
    
         
            +
            #    TMP_1.$$s = self, TMP_1),
         
     | 
| 
      
 360 
     | 
    
         
            +
            # foo.bar)(1, 2, $a);
         
     | 
| 
      
 361 
     | 
    
         
            +
            foo.JS.bar(1, 2){|arg| arg.JS.method + baz(3)}
         
     | 
| 
      
 362 
     | 
    
         
            +
            ```
         
     | 
| 
      
 363 
     | 
    
         
            +
             
     | 
| 
      
 364 
     | 
    
         
            +
            Note how `self` is set for the JavaScript function passed as an argument.  This
         
     | 
| 
      
 365 
     | 
    
         
            +
            allows normal Ruby block behavior to work when passing blocks to JavaScript
         
     | 
| 
      
 366 
     | 
    
         
            +
            methods.
         
     | 
| 
       318 
367 
     | 
    
         | 
| 
       319 
     | 
    
         
            -
             
     | 
| 
      
 368 
     | 
    
         
            +
            The `.JS.` syntax is recognized as a special token by the lexer, so if you have
         
     | 
| 
      
 369 
     | 
    
         
            +
            a Ruby method named `JS` that you want to call, you can add a space to call it:
         
     | 
| 
      
 370 
     | 
    
         
            +
             
     | 
| 
      
 371 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 372 
     | 
    
         
            +
            # call Ruby JS method on foo, call Ruby bar method on result
         
     | 
| 
      
 373 
     | 
    
         
            +
            foo. JS.bar
         
     | 
| 
      
 374 
     | 
    
         
            +
            ```
         
     | 
| 
      
 375 
     | 
    
         
            +
             
     | 
| 
      
 376 
     | 
    
         
            +
            ### Getting/Setting JavaScript Properties
         
     | 
| 
      
 377 
     | 
    
         
            +
             
     | 
| 
      
 378 
     | 
    
         
            +
            You can get JavaScript properties using the `recv.JS[:property]` syntax:
         
     | 
| 
      
 379 
     | 
    
         
            +
             
     | 
| 
      
 380 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 381 
     | 
    
         
            +
            # JavaScript: foo["bar"]
         
     | 
| 
      
 382 
     | 
    
         
            +
            foo.JS[:bar]
         
     | 
| 
      
 383 
     | 
    
         
            +
            ```
         
     | 
| 
      
 384 
     | 
    
         
            +
             
     | 
| 
      
 385 
     | 
    
         
            +
            This also works for JavaScript array access:
         
     | 
| 
      
 386 
     | 
    
         
            +
             
     | 
| 
      
 387 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 388 
     | 
    
         
            +
            # JavaScript: foo[2]
         
     | 
| 
      
 389 
     | 
    
         
            +
            foo.JS[2]
         
     | 
| 
      
 390 
     | 
    
         
            +
            ```
         
     | 
| 
      
 391 
     | 
    
         
            +
             
     | 
| 
      
 392 
     | 
    
         
            +
            You can set JavaScript properties using this as the left hand side in an
         
     | 
| 
      
 393 
     | 
    
         
            +
            assignment:
         
     | 
| 
      
 394 
     | 
    
         
            +
             
     | 
| 
      
 395 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 396 
     | 
    
         
            +
            # JavaScript: foo["bar"] = 1
         
     | 
| 
      
 397 
     | 
    
         
            +
            foo.JS[:bar] = 1
         
     | 
| 
      
 398 
     | 
    
         
            +
            ```
         
     | 
| 
      
 399 
     | 
    
         
            +
             
     | 
| 
      
 400 
     | 
    
         
            +
            This also works for setting values in a JavaScript array:
         
     | 
| 
      
 401 
     | 
    
         
            +
             
     | 
| 
      
 402 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 403 
     | 
    
         
            +
            # JavaScript: foo[2] = "a"
         
     | 
| 
      
 404 
     | 
    
         
            +
            foo.JS[2] = :a
         
     | 
| 
      
 405 
     | 
    
         
            +
            ```
         
     | 
| 
      
 406 
     | 
    
         
            +
             
     | 
| 
      
 407 
     | 
    
         
            +
            Like the `recv.JS.method` syntax, `.JS[` is recognized as a special token by
         
     | 
| 
      
 408 
     | 
    
         
            +
            the lexer, so if you want to call the Ruby `JS` method on a object and then
         
     | 
| 
      
 409 
     | 
    
         
            +
            call the Ruby `[]` method on the result, you can add a space:
         
     | 
| 
      
 410 
     | 
    
         
            +
             
     | 
| 
      
 411 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 412 
     | 
    
         
            +
            # call Ruby JS method on foo, call Ruby [] method on result with :a argument
         
     | 
| 
      
 413 
     | 
    
         
            +
            foo. JS[:a]
         
     | 
| 
      
 414 
     | 
    
         
            +
            ```
         
     | 
| 
      
 415 
     | 
    
         
            +
             
     | 
| 
      
 416 
     | 
    
         
            +
            ### Calling JavaScript Operators
         
     | 
| 
      
 417 
     | 
    
         
            +
             
     | 
| 
      
 418 
     | 
    
         
            +
            Opal has a `js` library in the stdlib that provides a `JS` module which can
         
     | 
| 
      
 419 
     | 
    
         
            +
            be used to call JavaScript operators such as `new`.  Example:
         
     | 
| 
      
 420 
     | 
    
         
            +
             
     | 
| 
      
 421 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 422 
     | 
    
         
            +
            require 'js'
         
     | 
| 
      
 423 
     | 
    
         
            +
             
     | 
| 
      
 424 
     | 
    
         
            +
            # new foo(bar)
         
     | 
| 
      
 425 
     | 
    
         
            +
            JS.new(foo, bar)
         
     | 
| 
      
 426 
     | 
    
         
            +
             
     | 
| 
      
 427 
     | 
    
         
            +
            # delete foo["bar"]
         
     | 
| 
      
 428 
     | 
    
         
            +
            JS.delete(foo, :bar)
         
     | 
| 
      
 429 
     | 
    
         
            +
             
     | 
| 
      
 430 
     | 
    
         
            +
            # "bar" in foo
         
     | 
| 
      
 431 
     | 
    
         
            +
            JS.in(:bar, foo)
         
     | 
| 
      
 432 
     | 
    
         
            +
             
     | 
| 
      
 433 
     | 
    
         
            +
            # foo instanceof bar
         
     | 
| 
      
 434 
     | 
    
         
            +
            JS.instanceof(foo, bar)
         
     | 
| 
      
 435 
     | 
    
         
            +
             
     | 
| 
      
 436 
     | 
    
         
            +
            # typeof foo
         
     | 
| 
      
 437 
     | 
    
         
            +
            JS.typeof(foo)
         
     | 
| 
      
 438 
     | 
    
         
            +
            ```
         
     | 
| 
      
 439 
     | 
    
         
            +
             
     | 
| 
      
 440 
     | 
    
         
            +
            ### Calling JavaScript Global Functions
         
     | 
| 
      
 441 
     | 
    
         
            +
             
     | 
| 
      
 442 
     | 
    
         
            +
            You can also use the `js` library to call JavaScript global functions via
         
     | 
| 
      
 443 
     | 
    
         
            +
            `JS.call`:
         
     | 
| 
      
 444 
     | 
    
         
            +
             
     | 
| 
      
 445 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 446 
     | 
    
         
            +
            require 'js'
         
     | 
| 
      
 447 
     | 
    
         
            +
             
     | 
| 
      
 448 
     | 
    
         
            +
            # parseFloat("1.1")
         
     | 
| 
      
 449 
     | 
    
         
            +
            JS.call(:parseFloat, "1.1")
         
     | 
| 
      
 450 
     | 
    
         
            +
            ```
         
     | 
| 
      
 451 
     | 
    
         
            +
             
     | 
| 
      
 452 
     | 
    
         
            +
            For convenience, `method_missing` is aliased to call, allowing you to call
         
     | 
| 
      
 453 
     | 
    
         
            +
            global JavaScript methods directly on the `JS` module:
         
     | 
| 
      
 454 
     | 
    
         
            +
             
     | 
| 
      
 455 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 456 
     | 
    
         
            +
            require 'js'
         
     | 
| 
      
 457 
     | 
    
         
            +
             
     | 
| 
      
 458 
     | 
    
         
            +
            # parseFloat("1.1")
         
     | 
| 
      
 459 
     | 
    
         
            +
            JS.parseFloat("1.1")
         
     | 
| 
      
 460 
     | 
    
         
            +
            ```
         
     | 
| 
      
 461 
     | 
    
         
            +
             
     | 
| 
      
 462 
     | 
    
         
            +
             
     | 
| 
      
 463 
     | 
    
         
            +
            ### Wrapping JavaScript Libraries
         
     | 
| 
      
 464 
     | 
    
         
            +
             
     | 
| 
      
 465 
     | 
    
         
            +
            If you want to integrate a JavaScript library with Opal, so that you can make Ruby calls, you can choose one of the following options:
         
     | 
| 
      
 466 
     | 
    
         
            +
             
     | 
| 
      
 467 
     | 
    
         
            +
            - **Use backticks:** This is the quickest, simplest approach to integrating: call the native JavaScript code directly; it may provide a slight performance benefit, but also produces "ugly" Ruby code riddled with JavaScript. It's ideal for occasional calls to a JavaScript library.
         
     | 
| 
      
 468 
     | 
    
         
            +
             
     | 
| 
      
 469 
     | 
    
         
            +
            - **Use `.JS`:** You can make direct JavaScript method calls on using the `recv.JS.method` syntax.  It is very similar to using backticks but looks more like ruby.
         
     | 
| 
      
 470 
     | 
    
         
            +
             
     | 
| 
      
 471 
     | 
    
         
            +
            - **Use `Native`:** `Native` provides a reasonable Ruby-like wrapper around JavaScript objects. This provides a quick in-term solution if no dedicated Ruby wrapper library exists.
         
     | 
| 
      
 472 
     | 
    
         
            +
             
     | 
| 
      
 473 
     | 
    
         
            +
            - **Create your own Wrapper Library:** If you use the library a lot, you can create your own Ruby library that wraps the JavaScript calls (which call `Native` or use backticks under the hood). This provides the best abstraction (eg. you can provide high-level calls that provide functionality, regardless of if the underlying JavaScript call flows change).
         
     | 
| 
      
 474 
     | 
    
         
            +
             
     | 
| 
      
 475 
     | 
    
         
            +
             
     | 
| 
      
 476 
     | 
    
         
            +
            ## Ruby from JavaScript
         
     | 
| 
      
 477 
     | 
    
         
            +
             
     | 
| 
      
 478 
     | 
    
         
            +
            Accessing classes and methods defined in Opal from the JavaScript runtime is
         
     | 
| 
       320 
479 
     | 
    
         
             
            possible via the `Opal` js object. The following class:
         
     | 
| 
       321 
480 
     | 
    
         | 
| 
       322 
481 
     | 
    
         
             
            ```ruby
         
     | 
| 
       323 
482 
     | 
    
         
             
            class Foo
         
     | 
| 
       324 
483 
     | 
    
         
             
              def bar
         
     | 
| 
       325 
     | 
    
         
            -
                puts "called bar on class Foo defined in  
     | 
| 
      
 484 
     | 
    
         
            +
                puts "called bar on class Foo defined in Ruby code"
         
     | 
| 
       326 
485 
     | 
    
         
             
              end
         
     | 
| 
       327 
486 
     | 
    
         
             
            end
         
     | 
| 
       328 
487 
     | 
    
         
             
            ```
         
     | 
| 
       329 
488 
     | 
    
         | 
| 
       330 
     | 
    
         
            -
            Can be accessed from  
     | 
| 
      
 489 
     | 
    
         
            +
            Can be accessed from JavaScript like this:
         
     | 
| 
       331 
490 
     | 
    
         | 
| 
       332 
491 
     | 
    
         
             
            ```javascript
         
     | 
| 
       333 
492 
     | 
    
         
             
            Opal.Foo.$new().$bar();
         
     | 
| 
       334 
     | 
    
         
            -
            // => "called bar on class Foo defined in  
     | 
| 
      
 493 
     | 
    
         
            +
            // => "called bar on class Foo defined in Ruby code"
         
     | 
| 
       335 
494 
     | 
    
         
             
            ```
         
     | 
| 
       336 
495 
     | 
    
         | 
| 
       337 
     | 
    
         
            -
            Remember that all  
     | 
| 
      
 496 
     | 
    
         
            +
            Remember that all Ruby methods are prefixed with a `$`.
         
     | 
| 
       338 
497 
     | 
    
         | 
| 
       339 
     | 
    
         
            -
            In the case that a method name can't be called directly due to a  
     | 
| 
      
 498 
     | 
    
         
            +
            In the case that a method name can't be called directly due to a JavaScript syntax error, you will need to call the method using bracket notation. For example, you can call `foo.$merge(...)` but not `foo.$merge!(...)`, `bar.$fetch('somekey')` but not `bar.$[]('somekey')`. Instead you would write it like this: `foo['$merge!'](...)` or `bar['$[]']('somekey')`.
         
     | 
| 
       340 
499 
     | 
    
         | 
| 
       341 
500 
     | 
    
         | 
| 
       342 
501 
     | 
    
         
             
            ### Hash
         
     | 
| 
       343 
502 
     | 
    
         | 
| 
       344 
     | 
    
         
            -
            Since  
     | 
| 
      
 503 
     | 
    
         
            +
            Since Ruby hashes are implemented directly with an Opal class, there's no "toll-free" bridging available (unlike with strings and arrays, for example). However, it's quite possible to interact with hashes from JavaScript:
         
     | 
| 
       345 
504 
     | 
    
         | 
| 
       346 
505 
     | 
    
         
             
            ```javascript
         
     | 
| 
       347 
506 
     | 
    
         
             
            var myHash = Opal.hash({a: 1, b: 2});
         
     | 
| 
         @@ -355,7 +514,7 @@ myHash.$fetch('z',''); 
     | 
|
| 
       355 
514 
     | 
    
         
             
            myHash.$update(Opal.hash({b: 20, c: 30}));
         
     | 
| 
       356 
515 
     | 
    
         
             
            // output of $inspect: {"a"=>10, "b"=>20, "c"=>30}
         
     | 
| 
       357 
516 
     | 
    
         
             
            myHash.$to_n(); // provided by the Native module
         
     | 
| 
       358 
     | 
    
         
            -
            // output: {"a": 10, "b": 20, "c": 30} aka a standard  
     | 
| 
      
 517 
     | 
    
         
            +
            // output: {"a": 10, "b": 20, "c": 30} aka a standard JavaScript object
         
     | 
| 
       359 
518 
     | 
    
         
             
            ```
         
     | 
| 
       360 
519 
     | 
    
         | 
| 
       361 
520 
     | 
    
         
             
            NOTE: Be aware `Hash#to_n` produces a duplicate copy of the hash.
         
     | 
| 
         @@ -364,32 +523,32 @@ NOTE: Be aware `Hash#to_n` produces a duplicate copy of the hash. 
     | 
|
| 
       364 
523 
     | 
    
         | 
| 
       365 
524 
     | 
    
         
             
            ### Method Missing
         
     | 
| 
       366 
525 
     | 
    
         | 
| 
       367 
     | 
    
         
            -
            Opal supports `method_missing`. This is a key feature of  
     | 
| 
      
 526 
     | 
    
         
            +
            Opal supports `method_missing`. This is a key feature of Ruby, and Opal wouldn't be much use without it! This page details the implementation of `method_missing` for Opal.
         
     | 
| 
       368 
527 
     | 
    
         | 
| 
       369 
528 
     | 
    
         
             
            #### Method dispatches
         
     | 
| 
       370 
529 
     | 
    
         | 
| 
       371 
     | 
    
         
            -
            Firstly, a  
     | 
| 
      
 530 
     | 
    
         
            +
            Firstly, a Ruby call `foo.bar 1, 2, 3` is compiled into the following JavaScript:
         
     | 
| 
       372 
531 
     | 
    
         | 
| 
       373 
532 
     | 
    
         
             
            ```javascript
         
     | 
| 
       374 
533 
     | 
    
         
             
            foo.$bar(1, 2, 3)
         
     | 
| 
       375 
534 
     | 
    
         
             
            ```
         
     | 
| 
       376 
535 
     | 
    
         | 
| 
       377 
     | 
    
         
            -
            This should be pretty easy to read. The `bar` method has a `$` prefix just to distinguish it from underlying  
     | 
| 
      
 536 
     | 
    
         
            +
            This should be pretty easy to read. The `bar` method has a `$` prefix just to distinguish it from underlying JavaScript properties, as well as Ruby ivars. Methods are compiled like this to make the generated code really readable.
         
     | 
| 
       378 
537 
     | 
    
         | 
| 
       379 
538 
     | 
    
         
             
            #### Handling `method_missing`
         
     | 
| 
       380 
539 
     | 
    
         | 
| 
       381 
     | 
    
         
            -
             
     | 
| 
      
 540 
     | 
    
         
            +
            JavaScript does not have an equivalent of `method_missing`, so how do we handle it? If a function is missing in JavaScript, then a language level exception will be raised.
         
     | 
| 
       382 
541 
     | 
    
         | 
| 
       383 
     | 
    
         
            -
            To get around this, we make use of our compiler. During parsing, we collect a list of all method calls made inside a  
     | 
| 
      
 542 
     | 
    
         
            +
            To get around this, we make use of our compiler. During parsing, we collect a list of all method calls made inside a Ruby file, and this gives us a list of all possible method calls. We then add stub methods to the root object prototype (an Opal object, not the global JavaScript Object) which will proxy our method missing calls for us.
         
     | 
| 
       384 
543 
     | 
    
         | 
| 
       385 
     | 
    
         
            -
            For example, assume the following  
     | 
| 
      
 544 
     | 
    
         
            +
            For example, assume the following Ruby script:
         
     | 
| 
       386 
545 
     | 
    
         | 
| 
       387 
546 
     | 
    
         
             
            ```ruby
         
     | 
| 
       388 
547 
     | 
    
         
             
            first 1, 2, 3
         
     | 
| 
       389 
548 
     | 
    
         
             
            second "wow".to_sym
         
     | 
| 
       390 
549 
     | 
    
         
             
            ```
         
     | 
| 
       391 
550 
     | 
    
         | 
| 
       392 
     | 
    
         
            -
            After parsing, we know we only ever call 3 methods: `[:first, :second, :to_sym]`. So, imagine we could just add these 3 methods to `BasicObject` in  
     | 
| 
      
 551 
     | 
    
         
            +
            After parsing, we know we only ever call 3 methods: `[:first, :second, :to_sym]`. So, imagine we could just add these 3 methods to `BasicObject` in Ruby, we would get something like this:
         
     | 
| 
       393 
552 
     | 
    
         | 
| 
       394 
553 
     | 
    
         
             
            ```ruby
         
     | 
| 
       395 
554 
     | 
    
         
             
            class BasicObject
         
     | 
| 
         @@ -407,19 +566,18 @@ class BasicObject 
     | 
|
| 
       407 
566 
     | 
    
         
             
            end
         
     | 
| 
       408 
567 
     | 
    
         
             
            ```
         
     | 
| 
       409 
568 
     | 
    
         | 
| 
       410 
     | 
    
         
            -
            It is obvious from here, that unless an object defines any given method, it will always resort in a dispatch to `method_missing` from one of our defined stub methods. This is how we get `method_missing` in  
     | 
| 
      
 569 
     | 
    
         
            +
            It is obvious from here, that unless an object defines any given method, it will always resort in a dispatch to `method_missing` from one of our defined stub methods. This is how we get `method_missing` in Opal.
         
     | 
| 
       411 
570 
     | 
    
         | 
| 
       412 
571 
     | 
    
         
             
            #### Optimising generated code
         
     | 
| 
       413 
572 
     | 
    
         | 
| 
       414 
     | 
    
         
            -
            To optimise the generated code slightly, we reduce the code output from the compiler into the following  
     | 
| 
      
 573 
     | 
    
         
            +
            To optimise the generated code slightly, we reduce the code output from the compiler into the following JavaScript:
         
     | 
| 
       415 
574 
     | 
    
         | 
| 
       416 
575 
     | 
    
         
             
            ```javascript
         
     | 
| 
       417 
576 
     | 
    
         
             
            Opal.add_stubs(["first", "second", "to_sym"]);
         
     | 
| 
       418 
577 
     | 
    
         
             
            ```
         
     | 
| 
       419 
578 
     | 
    
         | 
| 
       420 
     | 
    
         
            -
            You will see this at the top of all your generated  
     | 
| 
      
 579 
     | 
    
         
            +
            You will see this at the top of all your generated JavaScript files. This will add a stub method for all methods used in your file.
         
     | 
| 
       421 
580 
     | 
    
         | 
| 
       422 
581 
     | 
    
         
             
            #### Alternative approaches
         
     | 
| 
       423 
582 
     | 
    
         | 
| 
       424 
583 
     | 
    
         
             
            The old approach was to inline `method_missing` calls by checking for a method on **every method dispatch**. This is still supported via a parser option, but not recommended.
         
     | 
| 
       425 
     | 
    
         
            -
             
     |