1
0
Fork 0
mirror of https://github.com/rubyjs/therubyrhino synced 2023-03-27 23:21:34 -04:00

greatly simplify the rhino interface by tieing context to a scope

This commit is contained in:
Charles Lowell 2009-11-11 01:50:36 -05:00
parent a87b7f5085
commit 6239a0ba60
5 changed files with 50 additions and 76 deletions

View file

@ -5,40 +5,40 @@ module Rhino
class Context
class << self
def open
ContextFactory.new.call do |native|
yield new(native)
end
end
attr_reader :scope
def open_std(options = {})
open do |cxt|
yield cxt, cxt.init_standard_objects(options)
class << self
def open(options = {})
ContextFactory.new.call do |native|
yield new(native, options)
end
end
private :new
end
def initialize(native) #:nodoc:
def initialize(native, options) #:nodoc:
@native = native
end
def init_standard_objects(options = {})
NativeObject.new(@native.initStandardObjects(nil, options[:sealed] == true)).tap do |objects|
@scope = NativeObject.new(@native.initStandardObjects(nil, options[:sealed] == true))
unless options[:java]
for package in ["Packages", "java", "org", "com"]
objects.j.delete(package)
end
@scope.j.delete(package)
end
end
end
def eval(str, scope = @native.initStandardObjects())
def [](k)
@scope[k]
end
def []=(k,v)
@scope[k] = v
end
def eval(str)
str = str.to_s
begin
To.ruby @native.evaluateString(To.javascript(scope), str, "<eval>", 1, nil)
To.ruby @native.evaluateString(@scope.j, str, "<eval>", 1, nil)
rescue J::RhinoException => e
raise Rhino::RhinoError, e
end
@ -49,10 +49,6 @@ module Rhino
@native.factory.instruction_limit = limit
end
def standard
yield @native.initStandardObjects()
end
end
class Function < J::BaseFunction

View file

@ -6,7 +6,6 @@ module Rhino
def ruby(object)
case object
when *JS_UNDEF then nil
when Rhino::RubyObject then object
when J::Wrapper then object.unwrap
when J::Scriptable then NativeObject.new(object)
else object

View file

@ -18,66 +18,47 @@ describe Rhino::Context do
it "can embed primitive ruby object into javascript" do
Context.open do |cxt|
cxt.init_standard_objects.tap do |scope|
scope["foo"] = "Hello World"
cxt.eval("foo", scope).unwrap.should == "Hello World"
end
cxt['foo'] = "Hello World"
cxt.eval("foo").should == "Hello World"
end
end
describe "Initalizing Standard Javascript Objects" do
it "provides the standard objects without java integration by default" do
Context.open do |cxt|
cxt.init_standard_objects.tap do |scope|
scope["Object"].should_not be_nil
scope["Math"].should_not be_nil
scope["String"].should_not be_nil
scope["Function"].should_not be_nil
scope["Packages"].should be_nil
scope["java"].should be_nil
scope["org"].should be_nil
scope["com"].should be_nil
end
cxt["Object"].should_not be_nil
cxt["Math"].should_not be_nil
cxt["String"].should_not be_nil
cxt["Function"].should_not be_nil
cxt["Packages"].should be_nil
cxt["java"].should be_nil
cxt["org"].should be_nil
cxt["com"].should be_nil
end
end
it "provides unsealed standard object by default" do
Context.open do |cxt|
cxt.init_standard_objects.tap do |scope|
cxt.eval("Object.foop = 'blort'", scope)
scope["Object"]['foop'].should == 'blort'
end
cxt.eval("Object.foop = 'blort'")
cxt["Object"]['foop'].should == 'blort'
end
end
it "allows you to seal the standard objects so that they cannot be modified" do
Context.open do |cxt|
cxt.init_standard_objects(:sealed => true).tap do |scope|
Context.open(:sealed => true) do |cxt|
lambda {
cxt.eval("Object.foop = 'blort'", scope)
cxt.eval("Object.foop = 'blort'")
}.should raise_error(Rhino::RhinoError)
lambda {
cxt.eval("Object.prototype.toString = function() {}", scope)
cxt.eval("Object.prototype.toString = function() {}")
}.should raise_error(Rhino::RhinoError)
end
end
end
it "allows java integration to be turned on when initializing standard objects" do
Context.open do |cxt|
cxt.init_standard_objects(:java => true).tap do |scope|
scope["Packages"].should_not be_nil
end
end
end
it "provides a convenience method for initializing scopes" do
Context.open_std(:sealed => true, :java => true) do |cxt, scope|
scope["Object"].should_not be_nil
scope["java"].should_not be_nil
cxt.eval("new java.lang.String('foo')", scope).should == "foo"
Context.open(:java => true) do |cxt|
cxt["Packages"].should_not be_nil
end
end
end
@ -85,16 +66,14 @@ describe Rhino::Context do
it "can call ruby functions from javascript" do
Context.open do |cxt|
cxt.standard do |scope|
scope.put("say", scope, function {|word, times| word * times})
cxt.eval("say('Hello',2)", scope).should == "HelloHello"
end
cxt["say"] = function {|word, times| word * times}
cxt.eval("say('Hello',2)").should == "HelloHello"
end
end
it "can limit the number of instructions that are executed in the context" do
lambda {
Context.open_std do |cxt, scope|
Context.open do |cxt|
cxt.instruction_limit = 100 * 1000
timeout(1) do
cxt.eval('while (true);')

View file

@ -19,9 +19,9 @@ describe Rhino::NativeObject do
it "doesn't matter if you use a symbol or a string to set a value" do
@o[:foo] = "bar"
@o['foo'].unwrap.should == "bar"
@o['foo'].should == "bar"
@o['baz'] = "bang"
@o[:baz].unwrap.should == "bang"
@o[:baz].should == "bang"
end
it "returns nil when the value is null, null, or not defined" do

View file

@ -25,7 +25,7 @@ describe Rhino::To do
it "it unwraps wrapped java objects" do
Context.open do |cx|
scope = cx.init_standard_objects
scope = cx.scope
Java::JavaLang::String.new("Hello World").tap do |str|
J::NativeJavaObject.new(scope.j, str, str.getClass()).tap do |o|
To.ruby(o).should == "Hello World"