Class: Lua::Table

Inherits:
Object
  • Object
show all
Defined in:
lib/rlua.rb,
ext/rlua.c

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(*args) ⇒ Object

:nodoc:



244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
# File 'ext/rlua.c', line 244

static VALUE rbLuaTable_initialize(int argc, VALUE* argv, VALUE self)
{
  VALUE rbLuaState, ref;
  rb_scan_args(argc, argv, "11", &rbLuaState, &ref);

  VALUE stateSource = rb_obj_class(rbLuaState);
  if(stateSource != cLuaState && stateSource != cLuaTable && stateSource != cLuaFunction)
    rb_raise(rb_eTypeError, "wrong argument type %s (expected Lua::State, Lua::Table or Lua::Function)",
           rb_obj_classname(rbLuaState));

  VALUE rbState = rb_iv_get(rbLuaState, "@state");
  rb_iv_set(self, "@state", rbState);

  if(ref == Qnil) {
    lua_State* state;
    Data_Get_Struct(rbState, lua_State, state);

    lua_newtable(state);
    ref = rlua_makeref(state);
    lua_pop(state, 1);
  } else if(TYPE(ref) != T_FIXNUM) {
    rb_raise(rb_eTypeError, "wrong argument type %s (expected nil)", rb_obj_classname(ref));
  }

  rlua_add_ref_finalizer(rbState, ref, self);

  rb_iv_set(self, "@ref", ref);

  return self;
}

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method, *args) ⇒ Object

This method allows accessing Lua tables much as if they were Ruby objects.

Setting values can be done with a standard setter method: table.key = value is equivalent to table["key"] = value.

Getting values is as easy as setting: if the value is not a function, table.key is equivalent to table["key"].

If some table has a function as value, you can invoke methods on it. table.method(arg1, ..., argN) is equivalent to table["method"].call(arg1, ..., argN), and table.method!(arg1, ..., argN) is equivalent to table["method"].call(table, arg1, ..., argN). To get a reference to function you should use the table["method"] notation.

If the value is not present in table (which is equivalent to nil value in Lua) MethodNotFound exception will be raised; if you will attempt to call something which is not a function as a method, TypeError exception will be raised.



441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
# File 'ext/rlua.c', line 441

static VALUE rbLuaTable_method_missing(int argc, VALUE* argv, VALUE self)
{
  VALUE id, args;
  rb_scan_args(argc, argv, "1*", &id, &args);

  VALUE name = rb_str_new2(rb_id2name(rb_to_id(id)));

  int is_method = 0;
  int is_assign = 0;
  if(RSTRING_PTR(name)[RSTRING_LEN(name) - 1] == '!')
    is_method = 1;
  if(RSTRING_PTR(name)[RSTRING_LEN(name) - 1] == '=')
    is_assign = 1;

  if(is_method || is_assign)
    rb_str_resize(name, RSTRING_LEN(name) - 1);

  if(is_assign) {
    VALUE value;
    rb_scan_args(argc, argv, "11", &id, &value);
    return rbLuaTable_set(self, name, value);
  } else {
    VALUE value = rbLuaTable_get(self, name);
    if(value == Qnil) {
      return rb_call_super(argc, argv);
    } else if(rb_obj_class(value) != cLuaFunction) {
      if(is_method)
        rb_raise(rb_eTypeError, "%s is not a Lua::Function", RSTRING_PTR(name));
      return value;
    } else {
      if(is_method)
        rb_ary_unshift(args, self);
      return rbLuaFunction_call(value, args);
    }
  }
}

Class Method Details

.Lua::Table.next(table, key) ⇒ Array?

Iterates over a Lua table referenced by table. This function is analogue for Lua next function, but can be used even if Lua one is not defined.

You can use this method yourself, through it is easier to invoke to_a or to_hash.

Returns:

  • (Array, nil)


285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
# File 'ext/rlua.c', line 285

static VALUE rbLuaTable_next(VALUE self, VALUE table, VALUE index)
{
  lua_State* state;
  Data_Get_Struct(rb_iv_get(table, "@state"), lua_State, state);

  VALUE retval;

  rlua_push_var(state, table);                     // stack: |this|...
  rlua_push_var(state, index);                     //        |indx|this|...
  if(lua_next(state, -2) != 0) {                   //        |valu|key |this|...
    VALUE value, key;
    value = rlua_get_var(state);                   //        |valu|key |this|...
    lua_pop(state, 1);                             //        |key |this|...
    key = rlua_get_var(state);                     //        |key |this|...
    lua_pop(state, 2);                             //        ...

    retval = rb_ary_new();
    rb_ary_push(retval, key);
    rb_ary_push(retval, value);
  } else {                                         //        |this|...
    retval = Qnil;
    lua_pop(state, 1);                             //        ...
  }

  return retval;
}

Instance Method Details

#==(other) ⇒ Boolean

Compares this with other. May call __eq metamethod.

Returns:

  • (Boolean)


808
809
810
811
812
813
814
815
816
817
818
819
820
# File 'ext/rlua.c', line 808

static VALUE rbLua_equal(VALUE self, VALUE other)
{
  lua_State* state;
  Data_Get_Struct(rb_iv_get(self, "@state"), lua_State, state);

  int equal;
  rlua_push_var(state, self);           // stack: |this|...
  rlua_push_var(state, other);          //        |othr|this|...
  equal = lua_equal(state, -1, -2);     //        |othr|this|...
  lua_pop(state, 2);                    //        ...

  return equal ? Qtrue : Qfalse;
}

#[](key) ⇒ Object

Returns value associated with key in Lua table. May invoke Lua __index metamethod.



318
319
320
321
322
323
324
325
326
327
328
329
330
331
# File 'ext/rlua.c', line 318

static VALUE rbLuaTable_get(VALUE self, VALUE index)
{
  lua_State* state;
  Data_Get_Struct(rb_iv_get(self, "@state"), lua_State, state);

  VALUE value;
  rlua_push_var(state, self);                      // stack: |this|...
  rlua_push_var(state, index);                     //        |indx|this|...
  lua_gettable(state, -2);                         //        |valu|this|...
  value = rlua_get_var(state);                     //        |valu|this|...
  lua_pop(state, 2);                               //        ...

  return value;
}

#[]=(key) ⇒ Object

Sets value associated with key to value in Lua table. May invoke Lua __newindex metamethod.



339
340
341
342
343
344
345
346
347
348
349
350
351
# File 'ext/rlua.c', line 339

static VALUE rbLuaTable_set(VALUE self, VALUE index, VALUE value)
{
  lua_State* state;
  Data_Get_Struct(rb_iv_get(self, "@state"), lua_State, state);

  rlua_push_var(state, self);                      // stack: |this|...
  rlua_push_var(state, index);                     //        |indx|this|...
  rlua_push_var(state, value);                     //        |valu|indx|this|...
  lua_settable(state, -3);                         //        |this|...
  lua_pop(state, 1);                               //        ...

  return value;
}

#__equal(other) ⇒ Boolean

Compares this with other without calling any metamethods.

Returns:

  • (Boolean)


827
828
829
830
831
832
833
834
835
836
837
838
839
# File 'ext/rlua.c', line 827

static VALUE rbLua_rawequal(VALUE self, VALUE other)
{
  lua_State* state;
  Data_Get_Struct(rb_iv_get(self, "@state"), lua_State, state);

  int equal;
  rlua_push_var(state, self);           // stack: |this|...
  rlua_push_var(state, other);          //        |othr|this|...
  equal = lua_rawequal(state, -1, -2);  //        |othr|this|...
  lua_pop(state, 2);                    //        ...

  return equal ? Qtrue : Qfalse;
}

#__get(key) ⇒ Object

Returns value associated with key in Lua table without invoking any Lua metamethod (similar to rawget Lua function).



359
360
361
362
363
364
365
366
367
368
369
370
371
372
# File 'ext/rlua.c', line 359

static VALUE rbLuaTable_rawget(VALUE self, VALUE index)
{
  lua_State* state;
  Data_Get_Struct(rb_iv_get(self, "@state"), lua_State, state);

  VALUE value;
  rlua_push_var(state, self);                      // stack: |this|...
  rlua_push_var(state, index);                     //        |indx|this|...
  lua_rawget(state, -2);                           //        |valu|this|...
  value = rlua_get_var(state);                     //        |valu|this|...
  lua_pop(state, 2);                               //        ...

  return value;
}

#__lengthInteger

Returns table length as with Lua length # operator. Will not call any metamethod because __len metamethod has no effect when defined on table (and string).

Returns:

  • (Integer)


401
402
403
404
405
406
407
408
409
410
411
412
# File 'ext/rlua.c', line 401

static VALUE rbLuaTable_length(VALUE self)
{
  lua_State* state;
  Data_Get_Struct(rb_iv_get(self, "@state"), lua_State, state);

  VALUE length;
  rlua_push_var(state, self);                      // stack: |this|...
  length = INT2FIX(lua_objlen(state, -1));
  lua_pop(state, 1);                               //        ...

  return length;
}

#__metatableLua::Table?

Returns metatable of this table or nil if it is not present.

Returns:



767
768
769
770
# File 'ext/rlua.c', line 767

static VALUE rbLuaTable_get_metatable(VALUE self)
{
  return rbLua_get_metatable(self, self);
}

#__metatable=(metatable) ⇒ Object

Sets metatable for this table. metatable can be Lua::Table or Hash.



777
778
779
780
# File 'ext/rlua.c', line 777

static VALUE rbLuaTable_set_metatable(VALUE self, VALUE metatable)
{
  return rbLua_set_metatable(self, self, metatable);
}

#__set(key, value) ⇒ Object

Sets value associated with key to value in Lua table without invoking any Lua metamethod (similar to rawset Lua function).



380
381
382
383
384
385
386
387
388
389
390
391
392
# File 'ext/rlua.c', line 380

static VALUE rbLuaTable_rawset(VALUE self, VALUE index, VALUE value)
{
  lua_State* state;
  Data_Get_Struct(rb_iv_get(self, "@state"), lua_State, state);

  rlua_push_var(state, self);                      // stack: |this|...
  rlua_push_var(state, index);                     //        |indx|this|...
  rlua_push_var(state, value);                     //        |valu|indx|this|...
  lua_rawset(state, -3);                           //        |this|...
  lua_pop(state, 1);                               //        ...

  return value;
}

#each(&block) ⇒ Object

Traverses the table using Lua::Table.next function.



6
7
8
9
10
11
12
13
14
# File 'lib/rlua.rb', line 6

def each(&block)
  key = nil
  loop {
    key, value = *self.class.next(self, key)
    break if key.nil?
    block.call(key, value)
  }
  self
end

#inspect(trace = []) ⇒ Object

Recursively pretty-prints the table properly handling reference loops.

trace argument is internal, do not use it.



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/rlua.rb', line 40

def inspect(trace=[])
  if to_hash.empty?
    "L{}"
  elsif trace.include? self
    "L{...}"
  else
    trace << self
    v = []
    each { |key, value|
      s = ""
      if key.class == self.class
        s += key.inspect(trace)
      else
        s += key.inspect
      end
      s += " => "
      if value.class == self.class
        s += value.inspect(trace)
      else
        s += value.inspect
      end
      v << s
    }
    "L{#{v.join ', '}}"
  end
end

#to_aryObject Also known as: to_a

Converts table to array. Only integer indexes are used.



24
25
26
27
28
29
30
31
32
33
34
# File 'lib/rlua.rb', line 24

def to_ary
  ary = []
  1.upto(__length) { |i|
    if self[i]
      ary << self[i]
    else
      break
    end
  }
  ary
end

#to_hashObject

Non-recursively converts table to hash.



17
18
19
20
21
# File 'lib/rlua.rb', line 17

def to_hash
  hash = {}
  each { |k, v| hash[k] = v }
  hash
end