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:



259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
# File 'ext/rlua.c', line 259

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.



456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
# File 'ext/rlua.c', line 456

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)


300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
# File 'ext/rlua.c', line 300

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)


823
824
825
826
827
828
829
830
831
832
833
834
835
# File 'ext/rlua.c', line 823

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.



333
334
335
336
337
338
339
340
341
342
343
344
345
346
# File 'ext/rlua.c', line 333

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.



354
355
356
357
358
359
360
361
362
363
364
365
366
# File 'ext/rlua.c', line 354

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)


842
843
844
845
846
847
848
849
850
851
852
853
854
# File 'ext/rlua.c', line 842

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).



374
375
376
377
378
379
380
381
382
383
384
385
386
387
# File 'ext/rlua.c', line 374

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)


416
417
418
419
420
421
422
423
424
425
426
427
# File 'ext/rlua.c', line 416

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:



782
783
784
785
# File 'ext/rlua.c', line 782

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.



792
793
794
795
# File 'ext/rlua.c', line 792

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).



395
396
397
398
399
400
401
402
403
404
405
406
407
# File 'ext/rlua.c', line 395

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.



21
22
23
24
25
26
27
28
29
# File 'lib/rlua.rb', line 21

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.



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/rlua.rb', line 55

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.



39
40
41
42
43
44
45
46
47
48
49
# File 'lib/rlua.rb', line 39

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.



32
33
34
35
36
# File 'lib/rlua.rb', line 32

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