class Duktape::Context

Public Class Methods

new click to toggle source
new(complex_object: obj)

Returns a new JavaScript evaluation context.

static VALUE ctx_initialize(int argc, VALUE *argv, VALUE self)
{
  struct state *state;
  Data_Get_Struct(self, struct state, state);

  VALUE options;
  rb_scan_args(argc, argv, ":", &options);
  if (!NIL_P(options))
    state->complex_object = rb_hash_lookup2(options, ID2SYM(id_complex_object), state->complex_object);

  return Qnil;
}

Public Instance Methods

call_prop(name, params,...) → obj click to toggle source
call_prop([names,...], params,...) → obj

Call a function defined in the global scope with the given parameters. An Array of names can be given to call a function on a nested object.

ctx.call_prop("parseInt", "42")       #=> 42
ctx.call_prop(["Math", "pow"], 2, 10) #=> 1024
static VALUE ctx_call_prop(int argc, VALUE* argv, VALUE self)
{
  struct state *state;
  Data_Get_Struct(self, struct state, state);
  check_fatal(state);

  VALUE prop;
  rb_scan_args(argc, argv, "1*", &prop, NULL);

  ctx_get_nested_prop(state, prop);

  // Swap receiver and function
  duk_swap_top(state->ctx, -2);

  // Push arguments
  for (int i = 1; i < argc; i++) {
    ctx_push_ruby_object(state, argv[i]);
  }

  if (duk_pcall_method(state->ctx, (argc - 1)) == DUK_EXEC_ERROR) {
    raise_ctx_error(state);
  }

  VALUE res = ctx_stack_to_value(state, -1);
  duk_set_top(state->ctx, 0);
  return res;
}
complex_object → obj click to toggle source

Returns the default complex object, the value that would be returned if a JavaScript object had no representation in Ruby, such as a JavaScript Function. See also Context::new.

ctx.complex_object #=> #<Duktape::ComplexObject>
static VALUE ctx_complex_object(VALUE self)
{
  struct state *state;
  Data_Get_Struct(self, struct state, state);

  return state->complex_object;
}
ctx_define_function(name, &block) → nil click to toggle source

Define a function defined in the global scope and identified by a name.

ctx.ctx_define_function("hello_world") { |ctx| 'Hello world' } #=> nil
static VALUE ctx_define_function(VALUE self, VALUE prop)
{
  VALUE block;
  struct state *state;
  duk_context *ctx;

  // a block is required
  if (!rb_block_given_p())
    rb_raise(rb_eArgError, "Expected block");

  // get the context
  Data_Get_Struct(self, struct state, state);
  check_fatal(state);

  ctx = state->ctx;

  // the c function is available in the global scope
  duk_push_global_object(ctx);

  duk_push_c_function(ctx, ctx_call_pushed_function, DUK_VARARGS);

  block = rb_block_proc();
  rb_ary_push(state->blocks, block); // block will be properly garbage collected

  // both block and state are required by the pushed function
  duk_push_string(ctx, "block");
  duk_push_pointer(ctx, (void *) block);
  duk_def_prop(ctx, -3,  DUK_DEFPROP_HAVE_VALUE | DUK_DEFPROP_HAVE_WRITABLE | 0);

  duk_push_string(ctx, "state");
  duk_push_pointer(ctx, (void *) state);
  duk_def_prop(ctx, -3,  DUK_DEFPROP_HAVE_VALUE | DUK_DEFPROP_HAVE_WRITABLE | 0);

  duk_put_prop_string(ctx, -2, StringValueCStr(prop));

  return Qnil;
}
eval_string(string[, filename]) → obj click to toggle source

Evaluate JavaScript expression within context returning the value as a Ruby object.

ctx.eval_string("40 + 2") #=> 42
static VALUE ctx_eval_string(int argc, VALUE *argv, VALUE self)
{
  struct state *state;
  Data_Get_Struct(self, struct state, state);
  check_fatal(state);

  VALUE source;
  VALUE filename;

  rb_scan_args(argc, argv, "11", &source, &filename);

  if (NIL_P(filename)) {
    filename = sDefaultFilename;
  }

  StringValue(source);
  StringValue(filename);

  ctx_push_ruby_object(state, source);
  ctx_push_ruby_object(state, filename);

  if (duk_pcompile(state->ctx, DUK_COMPILE_EVAL) == DUK_EXEC_ERROR) {
    raise_ctx_error(state);
  }

  if (duk_pcall(state->ctx, 0) == DUK_EXEC_ERROR) {
    raise_ctx_error(state);
  }

  VALUE res = ctx_stack_to_value(state, -1);
  duk_set_top(state->ctx, 0);
  return res;
}
exec_string(string[, filename]) → nil click to toggle source

Evaluate JavaScript expression within context returning the value as a Ruby object.

ctx.exec_string("var foo = 42")
ctx.eval_string("foo") #=> 42
static VALUE ctx_exec_string(int argc, VALUE *argv, VALUE self)
{
  struct state *state;
  Data_Get_Struct(self, struct state, state);
  check_fatal(state);

  VALUE source;
  VALUE filename;

  rb_scan_args(argc, argv, "11", &source, &filename);

  if (NIL_P(filename)) {
    filename = sDefaultFilename;
  }

  StringValue(source);
  StringValue(filename);

  ctx_push_ruby_object(state, source);
  ctx_push_ruby_object(state, filename);

  if (duk_pcompile(state->ctx, 0) == DUK_EXEC_ERROR) {
    raise_ctx_error(state);
  }

  if (duk_pcall(state->ctx, 0) == DUK_EXEC_ERROR) {
    raise_ctx_error(state);
  }

  duk_set_top(state->ctx, 0);
  return Qnil;
}
get_prop(name) → obj click to toggle source
get_prop([names,...]) → obj

Access the property of the global object. An Array of names can be given to access the property on a nested object.

ctx.exec_string("var n = 42", "foo.js")
ctx.get_prop("n") #=> 42

ctx.get_prop(["Math", "PI"]) #=> 3.14
static VALUE ctx_get_prop(VALUE self, VALUE prop)
{
  struct state *state;
  Data_Get_Struct(self, struct state, state);
  check_fatal(state);

  ctx_get_nested_prop(state, prop);

  VALUE res = ctx_stack_to_value(state, -1);
  duk_set_top(state->ctx, 0);
  return res;
}