Class: Rufus::Lua::State

Inherits:
Object
  • Object
show all
Includes:
StateMixin
Defined in:
lib/rufus/lua/state.rb

Overview

A Lua state, wraps a Lua runtime.

require 'rufus/lua'
s = Rufus::Lua::State.new
s.eval "a = 1 + 2"

p s['a'] # => 3.0

Constant Summary

Constants included from StateMixin

Rufus::Lua::StateMixin::LUA_ENVIRONINDEX, Rufus::Lua::StateMixin::LUA_GCCOLLECT, Rufus::Lua::StateMixin::LUA_GCCOUNT, Rufus::Lua::StateMixin::LUA_GCCOUNTB, Rufus::Lua::StateMixin::LUA_GCRESTART, Rufus::Lua::StateMixin::LUA_GCSETPAUSE, Rufus::Lua::StateMixin::LUA_GCSETSTEPMUL, Rufus::Lua::StateMixin::LUA_GCSTEP, Rufus::Lua::StateMixin::LUA_GCSTOP, Rufus::Lua::StateMixin::LUA_GLOBALSINDEX, Rufus::Lua::StateMixin::LUA_MULTRET, Rufus::Lua::StateMixin::LUA_NOREF, Rufus::Lua::StateMixin::LUA_REFNIL, Rufus::Lua::StateMixin::LUA_REGISTRYINDEX, Rufus::Lua::StateMixin::SIMPLE_TYPES, Rufus::Lua::StateMixin::TBOOLEAN, Rufus::Lua::StateMixin::TFUNCTION, Rufus::Lua::StateMixin::TLIGHTUSERDATA, Rufus::Lua::StateMixin::TNIL, Rufus::Lua::StateMixin::TNONE, Rufus::Lua::StateMixin::TNUMBER, Rufus::Lua::StateMixin::TSTRING, Rufus::Lua::StateMixin::TTABLE, Rufus::Lua::StateMixin::TTHREAD, Rufus::Lua::StateMixin::TUSERDATA

Instance Method Summary collapse

Constructor Details

#initialize(include_libs = true) ⇒ State

Instantiates a Lua state (runtime).

Accepts an ‘include_libs’ optional arg. When set to true (the default, all the base Lua libs are loaded in the runtime.



384
385
386
387
388
389
390
391
392
393
394
395
396
397
# File 'lib/rufus/lua/state.rb', line 384

def initialize (include_libs=true)

  @pointer = Lib.luaL_newstate

  Lib.luaL_openlibs(@pointer) if include_libs

  #
  # preparing library methods cache

  class << @pointer
    attr_reader :__lib_method_cache
  end
  @pointer.instance_variable_set(:@__lib_method_cache, {})
end

Instance Method Details

#[](k) ⇒ Object

Returns a value set at the ‘global’ level in the state.

state.eval('a = 1 + 2')
puts state['a'] # => "3.0"


413
414
415
416
# File 'lib/rufus/lua/state.rb', line 413

def [] (k)

  k.index('.') ? self.eval("return #{k}") : get_global(k)
end

#closeObject

Closes the state.

It’s probably a good idea (mem leaks) to close a Lua state once you’re done with it.



503
504
505
506
507
508
# File 'lib/rufus/lua/state.rb', line 503

def close

  raise "State already closed" unless @pointer
  Lib.lua_close(@pointer)
  @pointer = nil
end

#eval(s) ⇒ Object

Evaluates a piece (string) of Lua code within the state.



402
403
404
405
# File 'lib/rufus/lua/state.rb', line 402

def eval (s)

  loadstring_and_call(s)
end

#function(name, &block) ⇒ Object

Binds a Ruby function (callback) in the top environment of Lua

require 'rubygems'
require 'rufus/lua'

s = Rufus::Lua::State.new

s.function 'key_up' do |table|
  table.inject({}) do |h, (k, v)|
    h[k.to_s.upcase] = v
  end
end

p s.eval(%{
  local table = {}
  table['CoW'] = 2
  table['pigs'] = 3
  table['DUCKS'] = 'none'
  return key_up(table)
}).to_h
  # => { 'COW' => 2.0, 'DUCKS => 'none', 'PIGS' => 3.0 }

s.close


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
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
# File 'lib/rufus/lua/state.rb', line 443

def function (name, &block)

  raise 'please pass a block for the body of the function' unless block

  callback = Proc.new do |state|

    args = block.arity > 0 ?
      (1..block.arity).collect { |i| stack_pop } :
      []

    result = block.call(*args)

    if result.is_a?(Hash)
      stack_push(result)
      1
    else
      result = Array(result)
      result.each { |e| stack_push(e) }
      result.size
    end
  end

  name = name.to_s

  name, index = if ri = name.rindex('.')
    #
    # bind in the given table

    table_name = name[0..ri-1]

    t = self.eval("return #{table_name}") rescue nil

    raise ArgumentError.new(
      "won't create automatically nested tables"
    ) if (not t) and table_name.index('.')

    t = self.eval("#{table_name} = {}; return #{table_name}") \
      unless t

    t.send(:load_onto_stack)

    [ name[ri+1..-1], -2 ]

  else
    #
    # bind function at the global level

    [ name, LUA_GLOBALSINDEX ]
  end

  Lib.lua_pushcclosure(@pointer, callback, 0)
  Lib.lua_setfield(@pointer, index, name)
end

#gc_collect!Object

Runs garbage collection



522
523
524
525
526
# File 'lib/rufus/lua/state.rb', line 522

def gc_collect!

  raise "State got closed, cannot proceed" unless @pointer
  Lib.lua_gc(@pointer, LUA_GCCOLLECT, 0)
end

#gc_countObject

Returns current amount of memory in KB in use by Lua



513
514
515
516
517
# File 'lib/rufus/lua/state.rb', line 513

def gc_count

  raise "State got closed, cannot proceed" unless @pointer
  Lib.lua_gc(@pointer, LUA_GCCOUNT, 0)
end

#gc_resumeObject

Restart garbage collection for this state



540
541
542
543
544
# File 'lib/rufus/lua/state.rb', line 540

def gc_resume

  raise "State got closed, cannot proceed" unless @pointer
  Lib.lua_gc(@pointer, LUA_GCRESTART, 0)
end

#gc_stopObject

Stop garbage collection for this state



531
532
533
534
535
# File 'lib/rufus/lua/state.rb', line 531

def gc_stop

  raise "State got closed, cannot proceed" unless @pointer
  Lib.lua_gc(@pointer, LUA_GCSTOP, 0)
end