mirror of
https://github.com/rubyjs/therubyrhino
synced 2023-03-27 23:21:34 -04:00
introduced Function#bind for the Ruby side;
setting this to nil does not end up as undefined - there seems no way to pass undefined as a function context thus pass the global object (mirroring non-strict mode)
This commit is contained in:
parent
7e3c2e8e1d
commit
176bf1ffe9
2 changed files with 47 additions and 8 deletions
|
@ -152,7 +152,18 @@ class Java::OrgMozillaJavascript::BaseFunction
|
||||||
# make JavaScript functions callable Ruby style e.g. `fn.call('42')`
|
# make JavaScript functions callable Ruby style e.g. `fn.call('42')`
|
||||||
def call(*args)
|
def call(*args)
|
||||||
context = Rhino::JS::Context.enter; scope = current_scope(context)
|
context = Rhino::JS::Context.enter; scope = current_scope(context)
|
||||||
__call__(context, scope, nil, Rhino.args_to_javascript(args, scope))
|
# calling as a (var) stored function - no this === undefined "use strict"
|
||||||
|
# TODO can't pass Undefined.instance as this - it's not a Scriptable !?
|
||||||
|
this = Rhino::JS::ScriptRuntime.getGlobal(context)
|
||||||
|
__call__(context, scope, this, Rhino.args_to_javascript(args, scope))
|
||||||
|
ensure
|
||||||
|
Rhino::JS::Context.exit
|
||||||
|
end
|
||||||
|
|
||||||
|
def bind(this, *args)
|
||||||
|
context = Rhino::JS::Context.enter; scope = current_scope(context)
|
||||||
|
args = Rhino.args_to_javascript(args, scope)
|
||||||
|
Rhino::JS::BoundFunction.new(context, scope, self, Rhino.to_javascript(this), args)
|
||||||
ensure
|
ensure
|
||||||
Rhino::JS::Context.exit
|
Rhino::JS::Context.exit
|
||||||
end
|
end
|
||||||
|
@ -167,7 +178,8 @@ class Java::OrgMozillaJavascript::BaseFunction
|
||||||
|
|
||||||
def methodcall(this, *args)
|
def methodcall(this, *args)
|
||||||
context = Rhino::JS::Context.enter; scope = current_scope(context)
|
context = Rhino::JS::Context.enter; scope = current_scope(context)
|
||||||
__call__(context, scope, Rhino.to_javascript(this), Rhino.args_to_javascript(args, scope))
|
args = Rhino.args_to_javascript(args, scope)
|
||||||
|
__call__(context, scope, Rhino.to_javascript(this), args)
|
||||||
ensure
|
ensure
|
||||||
Rhino::JS::Context.exit
|
Rhino::JS::Context.exit
|
||||||
end
|
end
|
||||||
|
|
|
@ -118,14 +118,14 @@ describe "NativeFunction" do
|
||||||
|
|
||||||
before do
|
before do
|
||||||
factory = Rhino::JS::ContextFactory.new
|
factory = Rhino::JS::ContextFactory.new
|
||||||
context, scope = nil, nil
|
@context, @scope = nil, nil
|
||||||
factory.call do |ctx|
|
factory.call do |ctx|
|
||||||
context = ctx
|
@context = ctx
|
||||||
scope = context.initStandardObjects(nil, false)
|
@scope = @context.initStandardObjects(nil, false)
|
||||||
end
|
end
|
||||||
factory.enterContext(context)
|
factory.enterContext(@context)
|
||||||
|
|
||||||
object = context.newObject(scope)
|
object = @context.newObject(@scope)
|
||||||
@object = Rhino::JS::ScriptableObject.getProperty(object, 'toString')
|
@object = Rhino::JS::ScriptableObject.getProperty(object, 'toString')
|
||||||
@object.instance_eval do
|
@object.instance_eval do
|
||||||
def to_h_properties
|
def to_h_properties
|
||||||
|
@ -141,7 +141,34 @@ describe "NativeFunction" do
|
||||||
it_should_behave_like 'ScriptableObject'
|
it_should_behave_like 'ScriptableObject'
|
||||||
|
|
||||||
it 'is callable' do
|
it 'is callable' do
|
||||||
@object.call.should == '[object Object]'
|
# NOTE: no implicit or bound this thus this === global
|
||||||
|
@object.call.should == '[object global]'
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'might be bind and called' do
|
||||||
|
@object.bind(@object).should be_a(Rhino::JS::Function)
|
||||||
|
@object.bind(@object).call.should == '[object Function]'
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'might be bind to a this context' do
|
||||||
|
@object.bind(@object).should be_a(Rhino::JS::Function)
|
||||||
|
@object.bind(@object).call.should == '[object Function]'
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'might be bind to a this with args' do
|
||||||
|
array = @context.newArray(@scope, [].to_java)
|
||||||
|
push = Rhino::JS::ScriptableObject.getProperty(array, 'push')
|
||||||
|
|
||||||
|
this = @context.newArray(@scope, [ 0 ].to_java)
|
||||||
|
push.bind(this, 1, 2).call(3, 4)
|
||||||
|
|
||||||
|
this.length.should == 5
|
||||||
|
5.times { |i| this.get(i, this).should == i }
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'might be method-called' do
|
||||||
|
an_obj = @context.newObject(@scope)
|
||||||
|
@object.methodcall(an_obj).should == '[object Object]'
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
Loading…
Add table
Reference in a new issue