1
0
Fork 0
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:
kares 2012-01-11 08:28:06 +01:00
parent 7e3c2e8e1d
commit 176bf1ffe9
2 changed files with 47 additions and 8 deletions

View file

@ -152,7 +152,18 @@ class Java::OrgMozillaJavascript::BaseFunction
# make JavaScript functions callable Ruby style e.g. `fn.call('42')`
def call(*args)
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
Rhino::JS::Context.exit
end
@ -167,7 +178,8 @@ class Java::OrgMozillaJavascript::BaseFunction
def methodcall(this, *args)
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
Rhino::JS::Context.exit
end

View file

@ -118,14 +118,14 @@ describe "NativeFunction" do
before do
factory = Rhino::JS::ContextFactory.new
context, scope = nil, nil
@context, @scope = nil, nil
factory.call do |ctx|
context = ctx
scope = context.initStandardObjects(nil, false)
@context = ctx
@scope = @context.initStandardObjects(nil, false)
end
factory.enterContext(context)
factory.enterContext(@context)
object = context.newObject(scope)
object = @context.newObject(@scope)
@object = Rhino::JS::ScriptableObject.getProperty(object, 'toString')
@object.instance_eval do
def to_h_properties
@ -141,7 +141,34 @@ describe "NativeFunction" do
it_should_behave_like 'ScriptableObject'
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