dienashorner 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +8 -0
- data/.rspec +1 -0
- data/Gemfile +13 -0
- data/LICENSE +201 -0
- data/README.md +157 -0
- data/Rakefile +18 -0
- data/dienashorner.gemspec +24 -0
- data/lib/nashorn/context.rb +188 -0
- data/lib/nashorn/convert.rb +57 -0
- data/lib/nashorn/error.rb +105 -0
- data/lib/nashorn/ext.rb +201 -0
- data/lib/nashorn/rhino/less.rb +84 -0
- data/lib/nashorn/rhino.rb +34 -0
- data/lib/nashorn/ruby/access.rb +68 -0
- data/lib/nashorn/ruby/attribute_access.rb +41 -0
- data/lib/nashorn/ruby/default_access.rb +37 -0
- data/lib/nashorn/ruby.rb +361 -0
- data/lib/nashorn/version.rb +3 -0
- data/lib/nashorn.rb +37 -0
- data/spec/nashorn/access_spec.rb +122 -0
- data/spec/nashorn/error_spec.rb +199 -0
- data/spec/nashorn/integration/bar.js +11 -0
- data/spec/nashorn/integration/foo.js +7 -0
- data/spec/nashorn/integration/index.js +7 -0
- data/spec/nashorn/integration/loop/element1.js +3 -0
- data/spec/nashorn/integration/loop/element2.js +8 -0
- data/spec/nashorn/integration/loop.js +3 -0
- data/spec/nashorn/integration_spec.rb +149 -0
- data/spec/nashorn/ruby_spec.rb +352 -0
- data/spec/nashorn_spec.rb +23 -0
- data/spec/spec_helper.rb +38 -0
- metadata +105 -0
@@ -0,0 +1,105 @@
|
|
1
|
+
module Nashorn
|
2
|
+
|
3
|
+
class JSError < StandardError
|
4
|
+
|
5
|
+
def initialize(native)
|
6
|
+
@native = native # might be a NativeException wrapping a Java Throwable
|
7
|
+
if ( value = self.value(true) ) != nil
|
8
|
+
if value.is_a?(Exception)
|
9
|
+
super "#{value.class.name}: #{value.message}"
|
10
|
+
elsif value.is_a?(JS::ScriptObject) # && @native.to_s.index('Error:')
|
11
|
+
super @native.message
|
12
|
+
else
|
13
|
+
super value
|
14
|
+
end
|
15
|
+
else
|
16
|
+
super cause ? cause.message : @native
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def inspect
|
21
|
+
"#<#{self.class.name}: #{message}>"
|
22
|
+
end
|
23
|
+
|
24
|
+
def message; super.to_s end
|
25
|
+
|
26
|
+
# Returns the (nested) cause of this error if any.
|
27
|
+
def cause
|
28
|
+
return @cause if defined?(@cause)
|
29
|
+
|
30
|
+
if @native.respond_to?(:cause) && @native.cause
|
31
|
+
@cause = @native.cause
|
32
|
+
else
|
33
|
+
@native.is_a?(JS::NashornException) ? @native : nil
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# Attempts to unwrap the (native) JavaScript/Java exception.
|
38
|
+
def unwrap
|
39
|
+
return @unwrap if defined?(@unwrap)
|
40
|
+
cause = self.cause
|
41
|
+
if cause && cause.is_a?(JS::NashornException)
|
42
|
+
e = cause.getCause
|
43
|
+
if e && e.is_a?(Java::OrgJrubyExceptions::RaiseException)
|
44
|
+
@unwrap = e.getException
|
45
|
+
else
|
46
|
+
@unwrap = e
|
47
|
+
end
|
48
|
+
else
|
49
|
+
@unwrap = nil
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# Return the thown (native) JavaScript value.
|
54
|
+
def value(unwrap = false)
|
55
|
+
return @value if defined?(@value) && ! unwrap
|
56
|
+
@value = get_thrown unless defined?(@value)
|
57
|
+
return @value.unwrap if unwrap && @value.respond_to?(:unwrap)
|
58
|
+
@value
|
59
|
+
end
|
60
|
+
alias_method :thrown, :value
|
61
|
+
|
62
|
+
# The backtrace is constructed using #javascript_backtrace + the Ruby part.
|
63
|
+
def backtrace
|
64
|
+
if js_backtrace = javascript_backtrace
|
65
|
+
js_backtrace.push(*super)
|
66
|
+
else
|
67
|
+
super
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# Returns the JavaScript back-trace part for this error (the script stack).
|
72
|
+
def javascript_backtrace(raw_elements = false)
|
73
|
+
return nil unless cause.is_a?(JS::NashornException)
|
74
|
+
JS::NashornException.getScriptFrames(cause).map do |element|
|
75
|
+
raw_elements ? element : element.to_s # ScriptStackElement
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
# jdk.nashorn.internal.runtime::ECMAException < NashornException has these :
|
80
|
+
|
81
|
+
def file_name
|
82
|
+
cause.respond_to?(:getFileName) ? cause.getFileName : nil
|
83
|
+
end
|
84
|
+
|
85
|
+
def line_number
|
86
|
+
cause.respond_to?(:getLineNumber) ? cause.getLineNumber : nil
|
87
|
+
end
|
88
|
+
|
89
|
+
def column_number
|
90
|
+
cause.respond_to?(:getColumnNumber) ? cause.getColumnNumber : nil
|
91
|
+
end
|
92
|
+
|
93
|
+
private
|
94
|
+
|
95
|
+
def get_thrown
|
96
|
+
if ( cause = self.cause ) && cause.respond_to?(:thrown)
|
97
|
+
cause.thrown # e.g. NashornException.getThrown
|
98
|
+
else
|
99
|
+
nil
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
data/lib/nashorn/ext.rb
ADDED
@@ -0,0 +1,201 @@
|
|
1
|
+
module Nashorn
|
2
|
+
module JS
|
3
|
+
|
4
|
+
JSObject.module_eval do
|
5
|
+
|
6
|
+
def [](key)
|
7
|
+
Nashorn.to_rb key.is_a?(Fixnum) ? getSlot(key) : getMember(key.to_s)
|
8
|
+
end
|
9
|
+
|
10
|
+
def []=(key, value)
|
11
|
+
js_val = Nashorn.to_js value
|
12
|
+
key.is_a?(Fixnum) ? setSlot(key, js_val) : setMember(key.to_s, js_val)
|
13
|
+
js_val
|
14
|
+
end
|
15
|
+
|
16
|
+
def has_key?(key); hasMember(key) end
|
17
|
+
alias_method :key?, :has_key?
|
18
|
+
alias_method :include?, :has_key?
|
19
|
+
|
20
|
+
def has_value?(val); raw_values.include?(val) end
|
21
|
+
alias_method :value?, :has_value?
|
22
|
+
|
23
|
+
def delete(key); removeMember(key) end
|
24
|
+
|
25
|
+
def length; keySet.size end
|
26
|
+
alias_method :size, :length
|
27
|
+
|
28
|
+
# enumerate the key value pairs contained in this javascript object. e.g.
|
29
|
+
#
|
30
|
+
# eval_js("{foo: 'bar', baz: 'bang'}").each do |key,value|
|
31
|
+
# puts "#{key} -> #{value} "
|
32
|
+
# end
|
33
|
+
#
|
34
|
+
# outputs foo -> bar baz -> bang
|
35
|
+
#
|
36
|
+
def each
|
37
|
+
each_raw { |key, val| yield key, Nashorn.to_rb(val) }
|
38
|
+
end
|
39
|
+
alias_method :each_pair, :each
|
40
|
+
|
41
|
+
def each_key
|
42
|
+
each_raw { |key, val| yield key }
|
43
|
+
end
|
44
|
+
|
45
|
+
def each_value
|
46
|
+
each_raw { |key, val| yield Nashorn.to_rb(val) }
|
47
|
+
end
|
48
|
+
|
49
|
+
def each_raw
|
50
|
+
for id in keySet do
|
51
|
+
yield id, getMember(id)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def keys
|
56
|
+
keySet.to_a
|
57
|
+
end
|
58
|
+
|
59
|
+
def values
|
60
|
+
raw_values.map { |val| Nashorn.to_rb(val) }
|
61
|
+
end
|
62
|
+
|
63
|
+
# Converts the native object to a hash. This isn't really a stretch since it's
|
64
|
+
# pretty much a hash in the first place.
|
65
|
+
def to_h
|
66
|
+
hash = {}
|
67
|
+
each do |key, val|
|
68
|
+
hash[key] = val.is_a?(JSObject) && ! val.equal?(self) ? val.to_h : val
|
69
|
+
end
|
70
|
+
hash
|
71
|
+
end
|
72
|
+
|
73
|
+
# def ==(other)
|
74
|
+
# equivalentValues(other) == true # JS ==
|
75
|
+
# end
|
76
|
+
#
|
77
|
+
# def eql?(other)
|
78
|
+
# self.class == other.class && self.==(other)
|
79
|
+
# end
|
80
|
+
|
81
|
+
# Convert this javascript object into a json string.
|
82
|
+
def to_json(*args)
|
83
|
+
to_h.to_json(*args)
|
84
|
+
end
|
85
|
+
|
86
|
+
# Delegate methods to JS object if possible when called from Ruby.
|
87
|
+
def method_missing(name, *args)
|
88
|
+
name_str = name.to_s
|
89
|
+
if name_str.end_with?('=') && args.size == 1 # writer -> JS put
|
90
|
+
self[ name_str[0...-1] ] = args[0]
|
91
|
+
else
|
92
|
+
if hasMember(name_str) && property = getMember(name_str)
|
93
|
+
if property.is_a?(JSObject) && property.isFunction
|
94
|
+
js_args = Nashorn.args_to_js(args)
|
95
|
+
Nashorn.to_rb property.__call__(self, js_args)
|
96
|
+
else
|
97
|
+
if args.size > 0
|
98
|
+
raise ArgumentError, "can't call '#{name_str}' with args: #{args.inspect} as it's a property"
|
99
|
+
end
|
100
|
+
Nashorn.to_rb property
|
101
|
+
end
|
102
|
+
else
|
103
|
+
super
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
# function :
|
109
|
+
|
110
|
+
# alias_method :__call__, :call
|
111
|
+
|
112
|
+
# make JavaScript functions callable Ruby style e.g. `fn.call('42')`
|
113
|
+
#
|
114
|
+
# NOTE: That invoking #call does not have the same semantics as
|
115
|
+
# JavaScript's Function#call but rather as Ruby's Method#call !
|
116
|
+
# Use #apply or #bind before calling to achieve the same effect.
|
117
|
+
def call(*args)
|
118
|
+
this = nil
|
119
|
+
Nashorn.to_rb __call__ this, Nashorn.args_to_js(args)
|
120
|
+
rescue JS::NashornException => e
|
121
|
+
raise Nashorn::JSError.new(e)
|
122
|
+
end
|
123
|
+
|
124
|
+
# bind a JavaScript function into the given (this) context
|
125
|
+
#def bind(this, *args)
|
126
|
+
# args = Nashorn.args_to_js(args)
|
127
|
+
# Rhino::JS::BoundFunction.new(self, Nashorn.to_js(this), args)
|
128
|
+
#end
|
129
|
+
|
130
|
+
# use JavaScript functions constructors from Ruby as `fn.new`
|
131
|
+
def new(*args)
|
132
|
+
newObject Nashorn.args_to_js(args)
|
133
|
+
rescue JS::NashornException => e
|
134
|
+
raise Nashorn::JSError.new(e)
|
135
|
+
end
|
136
|
+
|
137
|
+
# apply a function with the given context and (optional) arguments
|
138
|
+
# e.g. `fn.apply(obj, 1, 2)`
|
139
|
+
#
|
140
|
+
# NOTE: That #call from Ruby does not have the same semantics as
|
141
|
+
# JavaScript's Function#call but rather as Ruby's Method#call !
|
142
|
+
def apply(this, *args)
|
143
|
+
__call__ Nashorn.to_js(this), Nashorn.args_to_js(args)
|
144
|
+
rescue JS::NashornException => e
|
145
|
+
raise Nashorn::JSError.new(e)
|
146
|
+
end
|
147
|
+
alias_method :methodcall, :apply # V8::Function compatibility
|
148
|
+
|
149
|
+
end
|
150
|
+
|
151
|
+
AbstractJSObject.module_eval do
|
152
|
+
alias_method :raw_values, :values
|
153
|
+
alias_method :__call__, :call
|
154
|
+
end
|
155
|
+
|
156
|
+
ScriptObjectMirror.module_eval do # implements java.util.Map
|
157
|
+
|
158
|
+
# @private NOTE: duplicated from JSObject
|
159
|
+
def [](key)
|
160
|
+
Nashorn.to_rb key.is_a?(Fixnum) ? getSlot(key) : getMember(key.to_s)
|
161
|
+
end
|
162
|
+
|
163
|
+
# @private NOTE: duplicated from JSObject
|
164
|
+
def []=(key, value)
|
165
|
+
js_val = Nashorn.to_js value
|
166
|
+
key.is_a?(Fixnum) ? setSlot(key, js_val) : setMember(key.to_s, js_val)
|
167
|
+
js_val
|
168
|
+
end
|
169
|
+
|
170
|
+
# @private NOTE: duplicated from JSObject
|
171
|
+
def call(*args)
|
172
|
+
this = nil
|
173
|
+
Nashorn.to_rb __call__ this, Nashorn.args_to_js(args)
|
174
|
+
rescue JS::NashornException => e
|
175
|
+
raise Nashorn::JSError.new(e)
|
176
|
+
end
|
177
|
+
|
178
|
+
# def callMember(this, *args)
|
179
|
+
# this = nil
|
180
|
+
# Nashorn.to_rb __call__ this, Nashorn.args_to_js(args)
|
181
|
+
# rescue JS::NashornException => e
|
182
|
+
# raise Nashorn::JSError.new(e)
|
183
|
+
# end
|
184
|
+
|
185
|
+
#def to_s
|
186
|
+
# toString
|
187
|
+
#end
|
188
|
+
|
189
|
+
#def inspect
|
190
|
+
# id_hash = Java::JavaLang::System.identityHashCode(self)
|
191
|
+
# "<##{self.class.name}:0x#{Java::JavaLang::Integer.toHexString(id_hash)} #{to_s}>"
|
192
|
+
#end
|
193
|
+
|
194
|
+
end
|
195
|
+
|
196
|
+
NashornException.class_eval do
|
197
|
+
alias_method :value, :thrown
|
198
|
+
end
|
199
|
+
|
200
|
+
end
|
201
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
begin
|
2
|
+
require 'nashorn/rhino'
|
3
|
+
rescue LoadError => e
|
4
|
+
warn "[WARNING] Please install gem 'dienashorner' to use Less under JRuby."
|
5
|
+
raise e
|
6
|
+
end
|
7
|
+
|
8
|
+
require 'less/java_script'
|
9
|
+
|
10
|
+
module Less
|
11
|
+
module JavaScript
|
12
|
+
class NashornContext
|
13
|
+
|
14
|
+
def self.instance
|
15
|
+
return new # NOTE: for Rhino a context should be kept open per thread !
|
16
|
+
end
|
17
|
+
|
18
|
+
def initialize(globals = nil)
|
19
|
+
@context = Nashorn::Context.new :java => true
|
20
|
+
#if @context.respond_to?(:version)
|
21
|
+
# @context.version = '1.8'
|
22
|
+
# apply_1_8_compatibility! if @context.version.to_s != '1.8'
|
23
|
+
#else
|
24
|
+
# apply_1_8_compatibility!
|
25
|
+
#end
|
26
|
+
globals.each { |key, val| @context[key] = val } if globals
|
27
|
+
end
|
28
|
+
|
29
|
+
def unwrap
|
30
|
+
@context
|
31
|
+
end
|
32
|
+
|
33
|
+
def exec(&block)
|
34
|
+
@context.open(&block)
|
35
|
+
rescue Nashorn::JSError => e
|
36
|
+
handle_js_error(e)
|
37
|
+
end
|
38
|
+
|
39
|
+
def eval(source, options = nil)
|
40
|
+
source = source.encode('UTF-8') if source.respond_to?(:encode)
|
41
|
+
@context.eval("(#{source})")
|
42
|
+
rescue Nashorn::JSError => e
|
43
|
+
handle_js_error(e)
|
44
|
+
end
|
45
|
+
|
46
|
+
def call(properties, *args)
|
47
|
+
args.last.is_a?(::Hash) ? args.pop : {} # extract_option!
|
48
|
+
@context.eval(properties).call(*args)
|
49
|
+
rescue Nashorn::JSError => e
|
50
|
+
handle_js_error(e)
|
51
|
+
end
|
52
|
+
|
53
|
+
def method_missing(symbol, *args)
|
54
|
+
if @context.respond_to?(symbol)
|
55
|
+
@context.send(symbol, *args)
|
56
|
+
else
|
57
|
+
super
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
def handle_js_error(e)
|
64
|
+
|
65
|
+
raise e # TODO NOT IMPLEMENTED
|
66
|
+
|
67
|
+
#if e.value && ( e.value['message'] || e.value['type'].is_a?(String) )
|
68
|
+
# raise Less::ParseError.new(e, e.value) # LessError
|
69
|
+
#end
|
70
|
+
#if e.unwrap.to_s =~ /missing opening `\(`/
|
71
|
+
# raise Less::ParseError.new(e.unwrap.to_s)
|
72
|
+
#end
|
73
|
+
#if e.message && e.message[0, 12] == "Syntax Error"
|
74
|
+
# raise Less::ParseError.new(e)
|
75
|
+
#else
|
76
|
+
# raise Less::Error.new(e)
|
77
|
+
#end
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
Less::JavaScript.context_wrapper = Less::JavaScript::NashornContext
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'nashorn'
|
2
|
+
require 'nashorn/context'
|
3
|
+
|
4
|
+
module Nashorn
|
5
|
+
module Ruby
|
6
|
+
Scriptable.module_eval do
|
7
|
+
|
8
|
+
def get(name, scope = nil)
|
9
|
+
getMember(name)
|
10
|
+
end
|
11
|
+
|
12
|
+
def has(name, scope = nil)
|
13
|
+
hasMember(name)
|
14
|
+
end
|
15
|
+
|
16
|
+
def put(name, value, scope = nil)
|
17
|
+
setMember(name, value)
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
22
|
+
module JS
|
23
|
+
Scriptable = JSObject
|
24
|
+
JavaScriptException = NashornException
|
25
|
+
RhinoException = NashornException
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
if Object.const_defined?(:Rhino)
|
30
|
+
warn "therubyrhino seems to be loaded, Nashorn won't emulate Rhino"
|
31
|
+
else
|
32
|
+
$LOADED_FEATURES << 'rhino'
|
33
|
+
Rhino = Nashorn # the-borg!
|
34
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module Nashorn
|
2
|
+
module Ruby
|
3
|
+
|
4
|
+
autoload :DefaultAccess, 'nashorn/ruby/default_access'
|
5
|
+
autoload :AttributeAccess, 'nashorn/ruby/attribute_access'
|
6
|
+
|
7
|
+
class AccessBase
|
8
|
+
|
9
|
+
def has(object, name)
|
10
|
+
# try [](name) method :
|
11
|
+
if object.respond_to?(:'[]') && object.method(:'[]').arity == 1
|
12
|
+
unless internal?(name)
|
13
|
+
value = object.[](name) { return true }
|
14
|
+
return true unless value.nil?
|
15
|
+
end
|
16
|
+
end
|
17
|
+
yield
|
18
|
+
end
|
19
|
+
|
20
|
+
def get(object, name)
|
21
|
+
# try [](name) method :
|
22
|
+
if object.respond_to?(:'[]') && object.method(:'[]').arity == 1
|
23
|
+
value = begin
|
24
|
+
object[name]
|
25
|
+
rescue LocalJumpError
|
26
|
+
nil
|
27
|
+
end unless internal?(name)
|
28
|
+
return Nashorn.to_js(value) unless value.nil?
|
29
|
+
end
|
30
|
+
yield
|
31
|
+
end
|
32
|
+
|
33
|
+
def set(object, name, value)
|
34
|
+
# try []=(name, value) method :
|
35
|
+
if object.respond_to?(:'[]=') && object.method(:'[]=').arity == 2
|
36
|
+
rb_value = Nashorn.to_rb(value)
|
37
|
+
begin
|
38
|
+
return object[name] = rb_value
|
39
|
+
rescue LocalJumpError
|
40
|
+
end unless internal?(name)
|
41
|
+
end
|
42
|
+
yield
|
43
|
+
end
|
44
|
+
|
45
|
+
def has_slot(object, index, &block)
|
46
|
+
has(object, index, &block)
|
47
|
+
end
|
48
|
+
|
49
|
+
def get_slot(object, index, &block)
|
50
|
+
get(object, index, &block)
|
51
|
+
end
|
52
|
+
|
53
|
+
def set_slot(object, index, value, &block)
|
54
|
+
set(object, index, value, &block)
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
UNDERSCORES = '__'.freeze
|
60
|
+
|
61
|
+
def internal?(name) # e.g. '__iterator__', '__proto__'
|
62
|
+
name.is_a?(String) && name.start_with?(UNDERSCORES) && name.end_with?(UNDERSCORES)
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Nashorn
|
2
|
+
module Ruby
|
3
|
+
class AttributeAccess < AccessBase
|
4
|
+
|
5
|
+
def has(object, name)
|
6
|
+
if object.respond_to?(name.to_s) ||
|
7
|
+
object.respond_to?(:"#{name}=") # might have a writer but no reader
|
8
|
+
return true
|
9
|
+
end
|
10
|
+
super
|
11
|
+
end
|
12
|
+
|
13
|
+
def get(object, name)
|
14
|
+
name_sym = name.to_s.to_sym
|
15
|
+
if object.respond_to?(name_sym)
|
16
|
+
method = object.method(name_sym)
|
17
|
+
if method.arity == 0 && # check if it is an attr_reader
|
18
|
+
( object.respond_to?(:"#{name}=") ||
|
19
|
+
object.instance_variables.find { |var| var.to_sym == :"@#{name}" } )
|
20
|
+
return Nashorn.to_js(method.call)
|
21
|
+
else
|
22
|
+
return Function.wrap(method.unbind)
|
23
|
+
end
|
24
|
+
elsif object.respond_to?(:"#{name}=")
|
25
|
+
return nil # it does have the property but is non readable
|
26
|
+
end
|
27
|
+
super
|
28
|
+
end
|
29
|
+
|
30
|
+
def set(object, name, value)
|
31
|
+
if object.respond_to?(set_name = :"#{name}=")
|
32
|
+
rb_value = Nashorn.to_rb(value)
|
33
|
+
return object.send(set_name, rb_value)
|
34
|
+
end
|
35
|
+
super
|
36
|
+
end
|
37
|
+
alias_method :put, :set
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Nashorn
|
2
|
+
module Ruby
|
3
|
+
class DefaultAccess < AccessBase
|
4
|
+
|
5
|
+
def has(object, name)
|
6
|
+
if object.respond_to?(name.to_s) ||
|
7
|
+
object.respond_to?(:"#{name}=")
|
8
|
+
return true
|
9
|
+
end
|
10
|
+
super
|
11
|
+
end
|
12
|
+
|
13
|
+
def get(object, name)
|
14
|
+
if object.respond_to?(name_s = name.to_s)
|
15
|
+
method = object.method(name_s)
|
16
|
+
if method.arity == 0
|
17
|
+
return Nashorn.to_js(method.call)
|
18
|
+
else
|
19
|
+
return Function.wrap(method.unbind)
|
20
|
+
end
|
21
|
+
elsif object.respond_to?(:"#{name}=")
|
22
|
+
return nil
|
23
|
+
end
|
24
|
+
super
|
25
|
+
end
|
26
|
+
|
27
|
+
def set(object, name, value)
|
28
|
+
if object.respond_to?(set_name = :"#{name}=")
|
29
|
+
return object.send(set_name, Nashorn.to_rb(value))
|
30
|
+
end
|
31
|
+
super
|
32
|
+
end
|
33
|
+
alias_method :put, :set
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|