opal 0.5.0 → 0.5.2
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/Gemfile +0 -2
- data/README.md +1 -1
- data/Rakefile +11 -8
- data/lib/opal.rb +1 -1
- data/lib/opal/version.rb +1 -1
- data/opal.gemspec +1 -1
- data/{corelib → opal/core}/array.rb +47 -40
- data/{corelib → opal/core}/basic_object.rb +4 -0
- data/{corelib → opal/core}/boolean.rb +2 -6
- data/{corelib → opal/core}/class.rb +0 -0
- data/{corelib → opal/core}/comparable.rb +0 -0
- data/{corelib → opal/core}/encoding.rb +0 -0
- data/{corelib → opal/core}/enumerable.rb +160 -38
- data/opal/core/enumerator.rb +416 -0
- data/{corelib → opal/core}/error.rb +0 -0
- data/{corelib → opal/core}/hash.rb +38 -48
- data/{corelib → opal/core}/io.rb +13 -9
- data/{corelib → opal/core}/kernel.rb +75 -49
- data/{corelib → opal/core}/main.rb +0 -0
- data/{corelib → opal/core}/match_data.rb +0 -4
- data/{corelib → opal/core}/method.rb +0 -0
- data/{corelib → opal/core}/module.rb +24 -3
- data/{corelib → opal/core}/nil_class.rb +0 -4
- data/{corelib → opal/core}/numeric.rb +3 -4
- data/{corelib → opal/core}/proc.rb +0 -4
- data/{corelib → opal/core}/range.rb +0 -0
- data/{corelib → opal/core}/regexp.rb +0 -4
- data/{corelib → opal/core}/runtime.js +0 -0
- data/{corelib → opal/core}/string.rb +4 -6
- data/{corelib → opal/core}/struct.rb +3 -21
- data/{corelib → opal/core}/time.rb +0 -4
- data/opal/opal.rb +121 -0
- data/spec/corelib/array/select_spec.rb +14 -0
- data/spec/filters/20.rb +4 -0
- data/spec/filters/bugs/enumerable.rb +1 -48
- data/spec/filters/unsupported/enumerator.rb +13 -0
- data/spec/opal/compiler/irb_spec.rb +1 -0
- data/spec/rubyspecs +1 -0
- data/spec/{corelib → stdlib}/native/alias_native_spec.rb +6 -4
- data/spec/{corelib → stdlib}/native/each_spec.rb +3 -1
- data/spec/{corelib → stdlib}/native/element_reference_spec.rb +3 -1
- data/spec/stdlib/native/ext_spec.rb +19 -0
- data/spec/{corelib → stdlib}/native/initialize_spec.rb +4 -4
- data/spec/{corelib → stdlib}/native/method_missing_spec.rb +13 -1
- data/spec/{corelib → stdlib}/native/new_spec.rb +3 -1
- data/stdlib/enumerator.rb +1 -0
- data/stdlib/json.rb +1 -1
- data/stdlib/native.rb +483 -0
- metadata +52 -47
- data/corelib/enumerator.rb +0 -55
- data/corelib/native.rb +0 -270
- data/corelib/opal.rb +0 -88
- data/spec/corelib/native/ext_spec.rb +0 -5
- data/spec/filters/bugs/enumerator.rb +0 -6
data/opal/opal.rb
ADDED
@@ -0,0 +1,121 @@
|
|
1
|
+
require 'core/runtime'
|
2
|
+
require 'core/module'
|
3
|
+
require 'core/class'
|
4
|
+
require 'core/basic_object'
|
5
|
+
require 'core/kernel'
|
6
|
+
require 'core/nil_class'
|
7
|
+
require 'core/boolean'
|
8
|
+
require 'core/error'
|
9
|
+
require 'core/regexp'
|
10
|
+
require 'core/comparable'
|
11
|
+
require 'core/enumerable'
|
12
|
+
require 'core/enumerator'
|
13
|
+
require 'core/array'
|
14
|
+
require 'core/hash'
|
15
|
+
require 'core/string'
|
16
|
+
require 'core/match_data'
|
17
|
+
require 'core/encoding'
|
18
|
+
require 'core/numeric'
|
19
|
+
require 'core/proc'
|
20
|
+
require 'core/method'
|
21
|
+
require 'core/range'
|
22
|
+
require 'core/time'
|
23
|
+
require 'core/struct'
|
24
|
+
require 'core/io'
|
25
|
+
require 'core/main'
|
26
|
+
require 'native'
|
27
|
+
|
28
|
+
# regexp matches
|
29
|
+
$& = $~ = $` = $' = nil
|
30
|
+
|
31
|
+
# stub library path
|
32
|
+
$: = []
|
33
|
+
$" = []
|
34
|
+
|
35
|
+
# split lines
|
36
|
+
$/ = "\n"
|
37
|
+
$, = " "
|
38
|
+
|
39
|
+
ARGV = []
|
40
|
+
ARGF = Object.new
|
41
|
+
ENV = {}
|
42
|
+
|
43
|
+
$VERBOSE = false
|
44
|
+
$DEBUG = false
|
45
|
+
$SAFE = 0
|
46
|
+
|
47
|
+
RUBY_PLATFORM = 'opal'
|
48
|
+
RUBY_ENGINE = 'opal'
|
49
|
+
RUBY_VERSION = '1.9.3'
|
50
|
+
RUBY_ENGINE_VERSION = '0.5.2'
|
51
|
+
RUBY_RELEASE_DATE = '2013-11-11'
|
52
|
+
|
53
|
+
module Opal
|
54
|
+
def self.coerce_to(object, type, method)
|
55
|
+
return object if type === object
|
56
|
+
|
57
|
+
unless object.respond_to? method
|
58
|
+
raise TypeError, "no implicit conversion of #{object.class} into #{type}"
|
59
|
+
end
|
60
|
+
|
61
|
+
object.__send__ method
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.coerce_to!(object, type, method)
|
65
|
+
coerced = coerce_to(object, type, method)
|
66
|
+
|
67
|
+
unless type === coerced
|
68
|
+
raise TypeError, "can't convert #{object.class} into #{type} (#{object.class}##{method} gives #{coerced.class}"
|
69
|
+
end
|
70
|
+
|
71
|
+
coerced
|
72
|
+
end
|
73
|
+
|
74
|
+
def self.try_convert(object, type, method)
|
75
|
+
return object if type === object
|
76
|
+
|
77
|
+
if object.respond_to? method
|
78
|
+
object.__send__ method
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def self.compare(a, b)
|
83
|
+
compare = a <=> b
|
84
|
+
|
85
|
+
if `compare === nil`
|
86
|
+
raise ArgumentError, "comparison of #{a.class.name} with #{b.class.name} failed"
|
87
|
+
end
|
88
|
+
|
89
|
+
compare
|
90
|
+
end
|
91
|
+
|
92
|
+
def self.truthy?(value)
|
93
|
+
if value
|
94
|
+
true
|
95
|
+
else
|
96
|
+
false
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def self.falsy?(value)
|
101
|
+
if value
|
102
|
+
false
|
103
|
+
else
|
104
|
+
true
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def self.destructure(args)
|
109
|
+
%x{
|
110
|
+
if (args.length == 1) {
|
111
|
+
return args[0];
|
112
|
+
}
|
113
|
+
else if (args._isArray) {
|
114
|
+
return args;
|
115
|
+
}
|
116
|
+
else {
|
117
|
+
return $slice.call(args);
|
118
|
+
}
|
119
|
+
}
|
120
|
+
end
|
121
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
describe "Array#select" do
|
2
|
+
it "passes an array item into a single default-block parameter" do
|
3
|
+
[["ABC", "DEF"]].select do |x|
|
4
|
+
x.should == ["ABC", "DEF"]
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
it "splits an array item into a list of default block parameters" do
|
9
|
+
[["ABC", "DEF"]].select do |x,y|
|
10
|
+
x.should == "ABC"
|
11
|
+
y.should == "DEF"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
data/spec/filters/20.rb
ADDED
@@ -1,58 +1,11 @@
|
|
1
1
|
opal_filter "Enumerable" do
|
2
|
-
fails "Enumerable#
|
3
|
-
|
4
|
-
fails "Enumerable#drop_while passes elements to the block until the first false"
|
5
|
-
|
6
|
-
fails "Enumerable#each_slice raises an Argument Error if there is not a single parameter > 0"
|
7
|
-
|
8
|
-
fails "Enumerable#each_with_index provides each element to the block"
|
9
|
-
fails "Enumerable#each_with_index provides each element to the block and its index"
|
10
|
-
fails "Enumerable#each_with_index binds splat arguments properly"
|
11
|
-
fails "Enumerable#each_with_index passes extra parameters to each"
|
12
|
-
|
13
|
-
fails "Enumerable#entries passes arguments to each"
|
14
|
-
|
15
|
-
fails "Enumerable#first when passed an argument consumes only what is needed"
|
16
|
-
fails "Enumerable#first when passed an argument raises a TypeError if the passed argument is not numeric"
|
17
|
-
fails "Enumerable#first when passed an argument tries to convert the passed argument to an Integer using #to_int"
|
18
|
-
fails "Enumerable#first when passed an argument raises an ArgumentError when count is negative"
|
2
|
+
fails "Enumerable#cycle passed a number n as an argument raises an ArgumentError if more arguments are passed"
|
19
3
|
|
20
4
|
fails "Enumerable#grep can use $~ in the block when used with a Regexp"
|
21
5
|
|
22
|
-
fails "Enumerable#group_by returns a hash without default_proc"
|
23
|
-
fails "Enumerable#group_by gathers whole arrays as elements when each yields multiple"
|
24
|
-
|
25
|
-
fails "Enumerable#include? returns true if any element == argument for numbers"
|
26
|
-
fails "Enumerable#include? gathers whole arrays as elements when each yields multiple"
|
27
|
-
|
28
6
|
fails "Enumerable#inject returns nil when fails(legacy rubycon)"
|
29
7
|
fails "Enumerable#inject without inject arguments(legacy rubycon)"
|
30
|
-
fails "Enumerable#inject can take a symbol argument"
|
31
|
-
fails "Enumerable#inject ignores the block if two arguments"
|
32
|
-
fails "Enumerable#inject can take two argument"
|
33
|
-
|
34
|
-
fails "Enumerable#max raises an ArgumentError for incomparable elements"
|
35
|
-
fails "Enumerable#max gathers whole arrays as elements when each yields multiple"
|
36
|
-
|
37
|
-
fails "Enumerable#member? returns true if any element == argument for numbers"
|
38
|
-
fails "Enumerable#member? gathers whole arrays as elements when each yields multiple"
|
39
|
-
|
40
|
-
fails "Enumerable#min raises an ArgumentError for incomparable elements"
|
41
|
-
fails "Enumerable#min gathers whole arrays as elements when each yields multiple"
|
42
8
|
|
43
9
|
fails "Enumerable#reduce returns nil when fails(legacy rubycon)"
|
44
10
|
fails "Enumerable#reduce without inject arguments(legacy rubycon)"
|
45
|
-
fails "Enumerable#reduce can take a symbol argument"
|
46
|
-
fails "Enumerable#reduce ignores the block if two arguments"
|
47
|
-
fails "Enumerable#reduce can take two argument"
|
48
|
-
|
49
|
-
fails "Enumerable#select passes through the values yielded by #each_with_index"
|
50
|
-
fails "Enumerable#select returns an enumerator when no block given"
|
51
|
-
|
52
|
-
fails "Enumerable#take when passed an argument consumes only what is needed"
|
53
|
-
fails "Enumerable#take when passed an argument raises a TypeError if the passed argument is not numeric"
|
54
|
-
fails "Enumerable#take when passed an argument tries to convert the passed argument to an Integer using #to_int"
|
55
|
-
fails "Enumerable#take when passed an argument raises an ArgumentError when count is negative"
|
56
|
-
|
57
|
-
fails "Enumerable#to_a passes arguments to each"
|
58
11
|
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
opal_filter "Enumerator as generator" do
|
2
|
+
fails "Enumerator#next returns the next element of the enumeration"
|
3
|
+
fails "Enumerator#next raises a StopIteration exception at the end of the stream"
|
4
|
+
fails "Enumerator#next cannot be called again until the enumerator is rewound"
|
5
|
+
|
6
|
+
fails "Enumerator#rewind resets the enumerator to its initial state"
|
7
|
+
fails "Enumerator#rewind returns self"
|
8
|
+
fails "Enumerator#rewind has no effect on a new enumerator"
|
9
|
+
fails "Enumerator#rewind has no effect if called multiple, consecutive times"
|
10
|
+
fails "Enumerator#rewind does nothing if the object doesn't have a #rewind method"
|
11
|
+
fails "Enumerator#rewind works with peek to reset the position"
|
12
|
+
fails "Enumerator#rewind calls the enclosed object's rewind method if one exists"
|
13
|
+
end
|
data/spec/rubyspecs
CHANGED
@@ -1,7 +1,9 @@
|
|
1
|
-
|
1
|
+
require 'native'
|
2
|
+
|
3
|
+
describe "Native.alias_native" do
|
2
4
|
it "refers to an attribute on @native" do
|
3
5
|
Class.new {
|
4
|
-
include Native
|
6
|
+
include Native
|
5
7
|
|
6
8
|
alias_native :a, :a
|
7
9
|
}.new(`{ a: 2 }`).a.should == 2
|
@@ -9,7 +11,7 @@ describe "Native::Base.alias_native" do
|
|
9
11
|
|
10
12
|
it "refers to an attribute on @native and calls it if it's a function" do
|
11
13
|
Class.new {
|
12
|
-
include Native
|
14
|
+
include Native
|
13
15
|
|
14
16
|
alias_native :a, :a
|
15
17
|
}.new(`{ a: function() { return 42; } }`).a.should == 42
|
@@ -17,7 +19,7 @@ describe "Native::Base.alias_native" do
|
|
17
19
|
|
18
20
|
it "defaults old to new" do
|
19
21
|
Class.new {
|
20
|
-
include Native
|
22
|
+
include Native
|
21
23
|
|
22
24
|
alias_native :a
|
23
25
|
}.new(`{ a: 42 }`).a.should == 42
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'native'
|
2
|
+
|
3
|
+
describe Hash do
|
4
|
+
describe '#initialize' do
|
5
|
+
it "returns a hash with a nil value" do
|
6
|
+
h = Hash.new(`{a: null}`)
|
7
|
+
h[:a].should == nil
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
describe '#to_n' do
|
12
|
+
it "should return a js object representing hash" do
|
13
|
+
Hash.new({:a => 100, :b => 200}.to_n).should == {:a => 100, :b => 200}
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "Hash#to_n" do
|
19
|
+
end
|
@@ -1,17 +1,17 @@
|
|
1
1
|
require 'native'
|
2
2
|
|
3
|
-
describe "Native
|
4
|
-
it "works when Native
|
3
|
+
describe "Native#initialize" do
|
4
|
+
it "works when Native is included in a BasicObject" do
|
5
5
|
basic_class = Class.new(BasicObject)
|
6
6
|
basic_object = basic_class.new
|
7
7
|
lambda { basic_object.native? }.should raise_error(NoMethodError)
|
8
8
|
|
9
|
-
basic_class.send :include, Native
|
9
|
+
basic_class.send :include, Native
|
10
10
|
lambda { basic_class.new(`{}`) }.should_not raise_error
|
11
11
|
end
|
12
12
|
|
13
13
|
it "detects a non native object" do
|
14
14
|
object = Object.new
|
15
|
-
lambda { Native.new(object) }.should raise_error(ArgumentError)
|
15
|
+
lambda { Native::Object.new(object) }.should raise_error(ArgumentError)
|
16
16
|
end
|
17
17
|
end
|
@@ -1,4 +1,6 @@
|
|
1
|
-
|
1
|
+
require 'native'
|
2
|
+
|
3
|
+
describe "Native::Object#method_missing" do
|
2
4
|
it "should return values" do
|
3
5
|
Native(`{ a: 23 }`).a.should == 23
|
4
6
|
Native(`{ a: { b: 42 } }`).a.b.should == 42
|
@@ -36,4 +38,14 @@ describe "Native#method_missing" do
|
|
36
38
|
it "should pass the block as function" do
|
37
39
|
Native(`{ a: function(func) { return func(); } }`).a { 42 }.should == 42
|
38
40
|
end
|
41
|
+
|
42
|
+
it "should unwrap arguments" do
|
43
|
+
x = `{}`
|
44
|
+
|
45
|
+
Native(`{ a: function(a, b) { return a === b } }`).a(Native(x), x).should == true
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should wrap result" do
|
49
|
+
Native(`{ a: function() { return {}; } }`).a.class.should == Native::Object
|
50
|
+
end
|
39
51
|
end
|
@@ -0,0 +1 @@
|
|
1
|
+
# stub
|
data/stdlib/json.rb
CHANGED
data/stdlib/native.rb
ADDED
@@ -0,0 +1,483 @@
|
|
1
|
+
module Kernel
|
2
|
+
def native?(value)
|
3
|
+
`value == null || !value._klass`
|
4
|
+
end
|
5
|
+
|
6
|
+
def Native(obj)
|
7
|
+
if `#{obj} == null`
|
8
|
+
nil
|
9
|
+
elsif native?(obj)
|
10
|
+
Native::Object.new(obj)
|
11
|
+
else
|
12
|
+
obj
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def Array(object, *args, &block)
|
17
|
+
%x{
|
18
|
+
if (object == null || object === nil) {
|
19
|
+
return [];
|
20
|
+
}
|
21
|
+
else if (#{native?(object)}) {
|
22
|
+
return #{Native::Array.new(object, *args, &block).to_a};
|
23
|
+
}
|
24
|
+
else if (#{object.respond_to? :to_ary}) {
|
25
|
+
return #{object.to_ary};
|
26
|
+
}
|
27
|
+
else if (#{object.respond_to? :to_a}) {
|
28
|
+
return #{object.to_a};
|
29
|
+
}
|
30
|
+
else {
|
31
|
+
return [object];
|
32
|
+
}
|
33
|
+
}
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
module Native
|
38
|
+
def self.is_a?(object, klass)
|
39
|
+
%x{
|
40
|
+
try {
|
41
|
+
return #{object} instanceof #{Native.try_convert(klass)};
|
42
|
+
}
|
43
|
+
catch (e) {
|
44
|
+
return false;
|
45
|
+
}
|
46
|
+
}
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.try_convert(value)
|
50
|
+
%x{
|
51
|
+
if (#{native?(value)}) {
|
52
|
+
return #{value};
|
53
|
+
}
|
54
|
+
else if (#{value.respond_to? :to_n}) {
|
55
|
+
return #{value.to_n};
|
56
|
+
}
|
57
|
+
else {
|
58
|
+
return nil;
|
59
|
+
}
|
60
|
+
}
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.convert(value)
|
64
|
+
native = try_convert(value)
|
65
|
+
|
66
|
+
if `#{native} === nil`
|
67
|
+
raise ArgumentError, "the passed value isn't a native"
|
68
|
+
end
|
69
|
+
|
70
|
+
native
|
71
|
+
end
|
72
|
+
|
73
|
+
def self.call(obj, key, *args, &block)
|
74
|
+
%x{
|
75
|
+
var prop = #{obj}[#{key}];
|
76
|
+
|
77
|
+
if (prop == null) {
|
78
|
+
return nil;
|
79
|
+
}
|
80
|
+
else if (prop instanceof Function) {
|
81
|
+
if (block !== nil) {
|
82
|
+
args.push(block);
|
83
|
+
}
|
84
|
+
|
85
|
+
args = #{args.map {|value|
|
86
|
+
native = try_convert(value)
|
87
|
+
|
88
|
+
if nil === native
|
89
|
+
value
|
90
|
+
else
|
91
|
+
native
|
92
|
+
end
|
93
|
+
}};
|
94
|
+
|
95
|
+
return #{Native(`prop.apply(#{obj}, #{args})`)};
|
96
|
+
}
|
97
|
+
else if (#{native?(`prop`)}) {
|
98
|
+
return #{Native(`prop`)};
|
99
|
+
}
|
100
|
+
else {
|
101
|
+
return prop;
|
102
|
+
}
|
103
|
+
}
|
104
|
+
end
|
105
|
+
|
106
|
+
module Helpers
|
107
|
+
def alias_native(new, old = new, options = {})
|
108
|
+
if old.end_with? ?=
|
109
|
+
define_method new do |value|
|
110
|
+
`#@native[#{old[0 .. -2]}] = #{Native.convert(value)}`
|
111
|
+
|
112
|
+
value
|
113
|
+
end
|
114
|
+
else
|
115
|
+
if as = options[:as]
|
116
|
+
define_method new do |*args, &block|
|
117
|
+
if value = Native.call(@native, old, *args, &block)
|
118
|
+
as.new(value.to_n)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
else
|
122
|
+
define_method new do |*args, &block|
|
123
|
+
Native.call(@native, old, *args, &block)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def self.included(klass)
|
131
|
+
klass.extend Helpers
|
132
|
+
end
|
133
|
+
|
134
|
+
def initialize(native)
|
135
|
+
unless Kernel.native?(native)
|
136
|
+
Kernel.raise ArgumentError, "the passed value isn't native"
|
137
|
+
end
|
138
|
+
|
139
|
+
@native = native
|
140
|
+
end
|
141
|
+
|
142
|
+
def to_n
|
143
|
+
@native
|
144
|
+
end
|
145
|
+
|
146
|
+
class Object < BasicObject
|
147
|
+
include Native
|
148
|
+
|
149
|
+
def ==(other)
|
150
|
+
`#@native === #{Native.try_convert(other)}`
|
151
|
+
end
|
152
|
+
|
153
|
+
def has_key?(name)
|
154
|
+
`#@native.hasOwnProperty(#{name})`
|
155
|
+
end
|
156
|
+
|
157
|
+
alias key? has_key?
|
158
|
+
alias include? has_key?
|
159
|
+
alias member? has_key?
|
160
|
+
|
161
|
+
def each(*args)
|
162
|
+
if block_given?
|
163
|
+
%x{
|
164
|
+
for (var key in #@native) {
|
165
|
+
#{yield `key`, `#@native[key]`}
|
166
|
+
}
|
167
|
+
}
|
168
|
+
|
169
|
+
self
|
170
|
+
else
|
171
|
+
method_missing(:each, *args)
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
def [](key)
|
176
|
+
%x{
|
177
|
+
var prop = #@native[key];
|
178
|
+
|
179
|
+
if (prop instanceof Function) {
|
180
|
+
return prop;
|
181
|
+
}
|
182
|
+
else {
|
183
|
+
return #{::Native.call(@native, key)}
|
184
|
+
}
|
185
|
+
}
|
186
|
+
end
|
187
|
+
|
188
|
+
def []=(key, value)
|
189
|
+
native = Native.try_convert(value)
|
190
|
+
|
191
|
+
if `#{native} === nil`
|
192
|
+
`#@native[key] = #{value}`
|
193
|
+
else
|
194
|
+
`#@native[key] = #{native}`
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
def method_missing(mid, *args, &block)
|
199
|
+
%x{
|
200
|
+
if (mid.charAt(mid.length - 1) === '=') {
|
201
|
+
return #{self[mid.slice(0, mid.length - 1)] = args[0]};
|
202
|
+
}
|
203
|
+
else {
|
204
|
+
return #{::Native.call(@native, mid, *args, &block)};
|
205
|
+
}
|
206
|
+
}
|
207
|
+
end
|
208
|
+
|
209
|
+
def nil?
|
210
|
+
false
|
211
|
+
end
|
212
|
+
|
213
|
+
def is_a?(klass)
|
214
|
+
klass == Native
|
215
|
+
end
|
216
|
+
|
217
|
+
alias kind_of? is_a?
|
218
|
+
|
219
|
+
def instance_of?(klass)
|
220
|
+
klass == Native
|
221
|
+
end
|
222
|
+
|
223
|
+
def class
|
224
|
+
`self._klass`
|
225
|
+
end
|
226
|
+
|
227
|
+
def to_a(options = {}, &block)
|
228
|
+
Native::Array.new(@native, options, &block).to_a
|
229
|
+
end
|
230
|
+
|
231
|
+
def to_ary(options = {}, &block)
|
232
|
+
Native::Array.new(@native, options, &block)
|
233
|
+
end
|
234
|
+
|
235
|
+
def inspect
|
236
|
+
"#<Native:#{`String(#@native)`}>"
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
class Array
|
241
|
+
include Native
|
242
|
+
include Enumerable
|
243
|
+
|
244
|
+
def initialize(native, options = {}, &block)
|
245
|
+
super(native)
|
246
|
+
|
247
|
+
@get = options[:get] || options[:access]
|
248
|
+
@named = options[:named]
|
249
|
+
@set = options[:set] || options[:access]
|
250
|
+
@length = options[:length] || :length
|
251
|
+
@block = block
|
252
|
+
|
253
|
+
if `#{length} == null`
|
254
|
+
raise ArgumentError, "no length found on the array-like object"
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
def each(&block)
|
259
|
+
return enum_for :each unless block
|
260
|
+
|
261
|
+
index = 0
|
262
|
+
length = self.length
|
263
|
+
|
264
|
+
while index < length
|
265
|
+
block.call(self[index])
|
266
|
+
|
267
|
+
index += 1
|
268
|
+
end
|
269
|
+
|
270
|
+
self
|
271
|
+
end
|
272
|
+
|
273
|
+
def [](index)
|
274
|
+
result = case index
|
275
|
+
when String, Symbol
|
276
|
+
@named ? `#@native[#@named](#{index})` : `#@native[#{index}]`
|
277
|
+
|
278
|
+
when Integer
|
279
|
+
@get ? `#@native[#@get](#{index})` : `#@native[#{index}]`
|
280
|
+
end
|
281
|
+
|
282
|
+
if result
|
283
|
+
if @block
|
284
|
+
@block.call(result)
|
285
|
+
else
|
286
|
+
Native(result)
|
287
|
+
end
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
291
|
+
def []=(index, value)
|
292
|
+
if @set
|
293
|
+
`#@native[#@set](#{index}, #{value})`
|
294
|
+
else
|
295
|
+
`#@native[#{index}] = #{value}`
|
296
|
+
end
|
297
|
+
end
|
298
|
+
|
299
|
+
def last(count = nil)
|
300
|
+
if count
|
301
|
+
index = length - 1
|
302
|
+
result = []
|
303
|
+
|
304
|
+
while index >= 0
|
305
|
+
result << self[index]
|
306
|
+
index -= 1
|
307
|
+
end
|
308
|
+
|
309
|
+
result
|
310
|
+
else
|
311
|
+
self[length - 1]
|
312
|
+
end
|
313
|
+
end
|
314
|
+
|
315
|
+
def length
|
316
|
+
`#@native[#@length]`
|
317
|
+
end
|
318
|
+
|
319
|
+
def to_ary
|
320
|
+
self
|
321
|
+
end
|
322
|
+
|
323
|
+
def inspect
|
324
|
+
to_a.inspect
|
325
|
+
end
|
326
|
+
end
|
327
|
+
end
|
328
|
+
|
329
|
+
class Numeric
|
330
|
+
def to_n
|
331
|
+
`self.valueOf()`
|
332
|
+
end
|
333
|
+
end
|
334
|
+
|
335
|
+
class Proc
|
336
|
+
def to_n
|
337
|
+
self
|
338
|
+
end
|
339
|
+
end
|
340
|
+
|
341
|
+
class String
|
342
|
+
def to_n
|
343
|
+
`self.valueOf()`
|
344
|
+
end
|
345
|
+
end
|
346
|
+
|
347
|
+
class Regexp
|
348
|
+
def to_n
|
349
|
+
`self.valueOf()`
|
350
|
+
end
|
351
|
+
end
|
352
|
+
|
353
|
+
class MatchData
|
354
|
+
def to_n
|
355
|
+
@matches
|
356
|
+
end
|
357
|
+
end
|
358
|
+
|
359
|
+
class Struct
|
360
|
+
def initialize(*args)
|
361
|
+
if args.length == 1 && native?(args[0])
|
362
|
+
object = args[0]
|
363
|
+
|
364
|
+
members.each {|name|
|
365
|
+
instance_variable_set "@#{name}", Native(`#{object}[#{name}]`)
|
366
|
+
}
|
367
|
+
else
|
368
|
+
members.each_with_index {|name, index|
|
369
|
+
instance_variable_set "@#{name}", args[index]
|
370
|
+
}
|
371
|
+
end
|
372
|
+
end
|
373
|
+
|
374
|
+
def to_n
|
375
|
+
result = `{}`
|
376
|
+
|
377
|
+
each_pair {|name, value|
|
378
|
+
`#{result}[#{name}] = #{value.to_n}`
|
379
|
+
}
|
380
|
+
|
381
|
+
result
|
382
|
+
end
|
383
|
+
end
|
384
|
+
|
385
|
+
class Array
|
386
|
+
def to_n
|
387
|
+
%x{
|
388
|
+
var result = [];
|
389
|
+
|
390
|
+
for (var i = 0, length = self.length; i < length; i++) {
|
391
|
+
var obj = self[i];
|
392
|
+
|
393
|
+
if (#{`obj`.respond_to? :to_n}) {
|
394
|
+
result.push(#{`obj`.to_n});
|
395
|
+
}
|
396
|
+
else {
|
397
|
+
result.push(obj);
|
398
|
+
}
|
399
|
+
}
|
400
|
+
|
401
|
+
return result;
|
402
|
+
}
|
403
|
+
end
|
404
|
+
end
|
405
|
+
|
406
|
+
class Boolean
|
407
|
+
def to_n
|
408
|
+
`self.valueOf()`
|
409
|
+
end
|
410
|
+
end
|
411
|
+
|
412
|
+
class Time
|
413
|
+
def to_n
|
414
|
+
self
|
415
|
+
end
|
416
|
+
end
|
417
|
+
|
418
|
+
class NilClass
|
419
|
+
def to_n
|
420
|
+
`null`
|
421
|
+
end
|
422
|
+
end
|
423
|
+
|
424
|
+
class Hash
|
425
|
+
def initialize(defaults = undefined, &block)
|
426
|
+
%x{
|
427
|
+
if (defaults != null) {
|
428
|
+
if (defaults.constructor === Object) {
|
429
|
+
var map = self.map,
|
430
|
+
keys = self.keys;
|
431
|
+
|
432
|
+
for (var key in defaults) {
|
433
|
+
var value = defaults[key];
|
434
|
+
|
435
|
+
if (value && value.constructor === Object) {
|
436
|
+
map[key] = #{Hash.new(`value`)};
|
437
|
+
}
|
438
|
+
else {
|
439
|
+
map[key] = #{Native(`defaults[key]`)};
|
440
|
+
}
|
441
|
+
|
442
|
+
keys.push(key);
|
443
|
+
}
|
444
|
+
}
|
445
|
+
else {
|
446
|
+
self.none = defaults;
|
447
|
+
}
|
448
|
+
}
|
449
|
+
else if (block !== nil) {
|
450
|
+
self.proc = block;
|
451
|
+
}
|
452
|
+
|
453
|
+
return self;
|
454
|
+
}
|
455
|
+
end
|
456
|
+
|
457
|
+
def to_n
|
458
|
+
%x{
|
459
|
+
var result = {},
|
460
|
+
keys = self.keys,
|
461
|
+
map = self.map,
|
462
|
+
bucket,
|
463
|
+
value;
|
464
|
+
|
465
|
+
for (var i = 0, length = keys.length; i < length; i++) {
|
466
|
+
var key = keys[i],
|
467
|
+
obj = map[key];
|
468
|
+
|
469
|
+
if (#{`obj`.respond_to? :to_n}) {
|
470
|
+
result[key] = #{`obj`.to_n};
|
471
|
+
}
|
472
|
+
else {
|
473
|
+
result[key] = obj;
|
474
|
+
}
|
475
|
+
}
|
476
|
+
|
477
|
+
return result;
|
478
|
+
}
|
479
|
+
end
|
480
|
+
end
|
481
|
+
|
482
|
+
# native global
|
483
|
+
$$ = $global = Native(`Opal.global`)
|