rufus-lua 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.txt +8 -0
- data/CREDITS.txt +21 -0
- data/LICENSE.txt +21 -0
- data/README.txt +141 -0
- data/TODO.txt +19 -0
- data/lib/rufus-lua.rb +3 -0
- data/lib/rufus/lua.rb +30 -0
- data/lib/rufus/lua/lib.rb +97 -0
- data/lib/rufus/lua/objects.rb +246 -0
- data/lib/rufus/lua/state.rb +367 -0
- data/lib/rufus/lua/utils.rb +78 -0
- data/spec/spec.rb +9 -0
- metadata +75 -0
data/CHANGELOG.txt
ADDED
data/CREDITS.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
|
2
|
+
= CREDITS.txt rufus-lua gem
|
3
|
+
|
4
|
+
|
5
|
+
== authors
|
6
|
+
|
7
|
+
John Mettraux http://jmettraux.wordpress.com
|
8
|
+
Alain Hoang http://blogs.law.harvard.edu/hoanga/
|
9
|
+
|
10
|
+
|
11
|
+
== inspiration
|
12
|
+
|
13
|
+
http://rubyluabridge.rubyforge.org/
|
14
|
+
|
15
|
+
|
16
|
+
== finally
|
17
|
+
|
18
|
+
many thanks to the authors of ruby-ffi
|
19
|
+
|
20
|
+
http://kenai.com/projects/ruby-ffi
|
21
|
+
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
|
2
|
+
Copyright (c) 2009, John Mettraux, jmettraux@gmail.com
|
3
|
+
|
4
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
5
|
+
of this software and associated documentation files (the "Software"), to deal
|
6
|
+
in the Software without restriction, including without limitation the rights
|
7
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
+
copies of the Software, and to permit persons to whom the Software is
|
9
|
+
furnished to do so, subject to the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be included in
|
12
|
+
all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
15
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
16
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
17
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
18
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
19
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
20
|
+
THE SOFTWARE.
|
21
|
+
|
data/README.txt
ADDED
@@ -0,0 +1,141 @@
|
|
1
|
+
|
2
|
+
= rufus-lua
|
3
|
+
|
4
|
+
Lua embedded in Ruby, via Ruby FFI
|
5
|
+
|
6
|
+
Tested with Ruby 1.8.6, Ruby 1.9.1p0 and JRuby 1.1.6
|
7
|
+
|
8
|
+
|
9
|
+
== Lua
|
10
|
+
|
11
|
+
from
|
12
|
+
|
13
|
+
http://www.lua.org/
|
14
|
+
http://www.lua.org/about.html
|
15
|
+
|
16
|
+
"""
|
17
|
+
Lua is a powerful, fast, lightweight, embeddable scripting language.
|
18
|
+
|
19
|
+
Lua combines simple procedural syntax with powerful data description constructs based on associative arrays and extensible semantics. Lua is dynamically typed, runs by interpreting bytecode for a register-based virtual machine, and has automatic memory management with incremental garbage collection, making it ideal for configuration, scripting, and rapid prototyping.
|
20
|
+
"""
|
21
|
+
|
22
|
+
|
23
|
+
== other Ruby and Lua bridges / connectors
|
24
|
+
|
25
|
+
|
26
|
+
http://rubyluabridge.rubyforge.org/
|
27
|
+
http://raa.ruby-lang.org/project/ruby-lua
|
28
|
+
|
29
|
+
|
30
|
+
== using rufus-lua
|
31
|
+
|
32
|
+
If you don't have liblua.dylib on your system, scroll until "compiling liblua.dylib" to learn how to get it.
|
33
|
+
|
34
|
+
sudo gem install rufus-lua
|
35
|
+
|
36
|
+
then
|
37
|
+
|
38
|
+
require 'rubygems'
|
39
|
+
require 'rufus/lua'
|
40
|
+
|
41
|
+
s = Rufus::Lua::State.new
|
42
|
+
|
43
|
+
puts s.eval("return table.concat({ 'hello', 'from', 'Lua' }, ' ')")
|
44
|
+
#
|
45
|
+
# => "Hello from Lua"
|
46
|
+
|
47
|
+
s.close
|
48
|
+
|
49
|
+
rufus-lua's rdoc is at http://rufus.rubyforge.org/rufus-lua/
|
50
|
+
|
51
|
+
|
52
|
+
== compiling liblua.dylib
|
53
|
+
|
54
|
+
original instructions by Adrian Perez at :
|
55
|
+
|
56
|
+
http://lua-users.org/lists/lua-l/2006-09/msg00894.html
|
57
|
+
|
58
|
+
get the source at
|
59
|
+
|
60
|
+
http://www.lua.org/ftp/lua-5.1.4.tar.gz
|
61
|
+
|
62
|
+
then
|
63
|
+
|
64
|
+
tar xzvf lua-5.1.4.tar.gz
|
65
|
+
cd lua-5.1.4
|
66
|
+
|
67
|
+
modify the file src/Makefile as per http://lua-users.org/lists/lua-l/2006-09/msg00894.html
|
68
|
+
|
69
|
+
make
|
70
|
+
make masocx # or make linux ...
|
71
|
+
make -C src src liblua.dylib
|
72
|
+
|
73
|
+
sudo cp src/liblua.dylib /usr/local/lib/
|
74
|
+
|
75
|
+
|
76
|
+
== build dependencies
|
77
|
+
|
78
|
+
You need to add the github gems to your gem sources
|
79
|
+
gem sources -a http://gems.github.com
|
80
|
+
|
81
|
+
The following gems are needed to run the specs
|
82
|
+
mislav-hanna
|
83
|
+
install bacon
|
84
|
+
|
85
|
+
|
86
|
+
== dependencies
|
87
|
+
|
88
|
+
the ruby gem 'ffi'
|
89
|
+
|
90
|
+
|
91
|
+
== mailing list
|
92
|
+
|
93
|
+
On the rufus-ruby list :
|
94
|
+
|
95
|
+
http://groups.google.com/group/rufus-ruby
|
96
|
+
|
97
|
+
|
98
|
+
== issue tracker
|
99
|
+
|
100
|
+
http://rubyforge.org/tracker/?atid=18584&group_id=4812&func=browse
|
101
|
+
|
102
|
+
|
103
|
+
== irc
|
104
|
+
|
105
|
+
irc.freenode.net #ruote
|
106
|
+
|
107
|
+
|
108
|
+
== source
|
109
|
+
|
110
|
+
http://github.com/jmettraux/rufus-lua
|
111
|
+
|
112
|
+
git clone git://github.com/jmettraux/rufus-lua.git
|
113
|
+
|
114
|
+
|
115
|
+
== credits
|
116
|
+
|
117
|
+
many thanks to the authors of Ruby FFI, and of Lua
|
118
|
+
|
119
|
+
http://kenai.com/projects/ruby-ffi/
|
120
|
+
http://lua.org/
|
121
|
+
|
122
|
+
|
123
|
+
== authors
|
124
|
+
|
125
|
+
John Mettraux, jmettraux@gmail.com, http://jmettraux.wordpress.com
|
126
|
+
Alain Hoang, http://blogs.law.harvard.edu/hoanga/
|
127
|
+
|
128
|
+
|
129
|
+
== the rest of Rufus
|
130
|
+
|
131
|
+
http://rufus.rubyforge.org
|
132
|
+
|
133
|
+
|
134
|
+
== license
|
135
|
+
|
136
|
+
MIT
|
137
|
+
|
138
|
+
Lua itself is licensed under the MIT license as well :
|
139
|
+
|
140
|
+
http://www.lua.org/license.html
|
141
|
+
|
data/TODO.txt
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
|
2
|
+
[o] spec table.free()
|
3
|
+
[o] function.call()
|
4
|
+
[o] Table#[]
|
5
|
+
[o] Table + Enumerable (not necessarily)
|
6
|
+
|
7
|
+
[x] State#stack_ready() maybe : NO !
|
8
|
+
|
9
|
+
[o] better protection for State methods (into lib ?)
|
10
|
+
|
11
|
+
[o] fix coroutine & co / memoization (make it better later)
|
12
|
+
[o] fib.lua, use local, bench ! (2 times faster almost)
|
13
|
+
|
14
|
+
[ ] add GC control methods (Alain)
|
15
|
+
[ ] Add method to disable GC
|
16
|
+
[ ] Add method to enable GC
|
17
|
+
[ ] Look at parameters in Lua GC that can be tweaked
|
18
|
+
[ ] Add method to tune GC parameters
|
19
|
+
|
data/lib/rufus-lua.rb
ADDED
data/lib/rufus/lua.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2009, John Mettraux, jmettraux@gmail.com
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
5
|
+
# of this software and associated documentation files (the "Software"), to deal
|
6
|
+
# in the Software without restriction, including without limitation the rights
|
7
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
+
# copies of the Software, and to permit persons to whom the Software is
|
9
|
+
# furnished to do so, subject to the following conditions:
|
10
|
+
#
|
11
|
+
# The above copyright notice and this permission notice shall be included in
|
12
|
+
# all copies or substantial portions of the Software.
|
13
|
+
#
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
15
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
16
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
17
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
18
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
19
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
20
|
+
# THE SOFTWARE.
|
21
|
+
#
|
22
|
+
# Made in Japan.
|
23
|
+
#++
|
24
|
+
|
25
|
+
require 'rufus/lua/lib'
|
26
|
+
|
27
|
+
require 'rufus/lua/state'
|
28
|
+
require 'rufus/lua/utils'
|
29
|
+
require 'rufus/lua/objects'
|
30
|
+
|
@@ -0,0 +1,97 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2009, John Mettraux, jmettraux@gmail.com
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
5
|
+
# of this software and associated documentation files (the "Software"), to deal
|
6
|
+
# in the Software without restriction, including without limitation the rights
|
7
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
+
# copies of the Software, and to permit persons to whom the Software is
|
9
|
+
# furnished to do so, subject to the following conditions:
|
10
|
+
#
|
11
|
+
# The above copyright notice and this permission notice shall be included in
|
12
|
+
# all copies or substantial portions of the Software.
|
13
|
+
#
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
15
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
16
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
17
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
18
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
19
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
20
|
+
# THE SOFTWARE.
|
21
|
+
#
|
22
|
+
# Made in Japan.
|
23
|
+
#++
|
24
|
+
|
25
|
+
|
26
|
+
#require 'rubygems' # done by the 'client' code
|
27
|
+
require 'ffi'
|
28
|
+
|
29
|
+
|
30
|
+
module Rufus
|
31
|
+
module Lua
|
32
|
+
|
33
|
+
module Lib
|
34
|
+
extend FFI::Library
|
35
|
+
|
36
|
+
#
|
37
|
+
# locate dylib
|
38
|
+
|
39
|
+
paths = Array(ENV['LUA_LIB'] || %w{
|
40
|
+
/opt/local/lib/liblua.dylib
|
41
|
+
/usr/local/lib/liblua.dylib
|
42
|
+
/usr/local/lib/liblua.so
|
43
|
+
})
|
44
|
+
|
45
|
+
path = paths.find { |path| File.exist?(path) }
|
46
|
+
|
47
|
+
raise(
|
48
|
+
"didn't find the lua dylib on your system, " +
|
49
|
+
"see http://rufus.rubyforge.org/rufus-lua/ to learn how to get it"
|
50
|
+
) unless path
|
51
|
+
|
52
|
+
ffi_lib(path)
|
53
|
+
|
54
|
+
#
|
55
|
+
# attach functions
|
56
|
+
|
57
|
+
attach_function :strlen, [ :string ], :int
|
58
|
+
|
59
|
+
attach_function :lua_close, [ :pointer ], :void
|
60
|
+
|
61
|
+
attach_function :luaL_openlibs, [ :pointer ], :void
|
62
|
+
|
63
|
+
attach_function :lua_pcall, [ :pointer, :int, :int, :int ], :int
|
64
|
+
#attach_function :lua_resume, [ :pointer, :int ], :int
|
65
|
+
|
66
|
+
attach_function :lua_toboolean, [ :pointer, :int ], :int
|
67
|
+
attach_function :lua_tonumber, [ :pointer, :int ], :float
|
68
|
+
attach_function :lua_tolstring, [ :pointer, :int, :pointer ], :string
|
69
|
+
|
70
|
+
attach_function :lua_type, [ :pointer, :int ], :int
|
71
|
+
attach_function :lua_typename, [ :pointer, :int ], :string
|
72
|
+
|
73
|
+
attach_function :lua_gettop, [ :pointer ], :int
|
74
|
+
attach_function :lua_settop, [ :pointer, :int ], :void
|
75
|
+
|
76
|
+
attach_function :lua_objlen, [ :pointer, :int ], :int
|
77
|
+
attach_function :lua_getfield, [ :pointer, :int, :string ], :pointer
|
78
|
+
attach_function :lua_gettable, [ :pointer, :int ], :void
|
79
|
+
|
80
|
+
attach_function :lua_next, [ :pointer, :int ], :int
|
81
|
+
|
82
|
+
attach_function :lua_pushnil, [ :pointer ], :pointer
|
83
|
+
attach_function :lua_pushboolean, [ :pointer, :int ], :pointer
|
84
|
+
attach_function :lua_pushinteger, [ :pointer, :int ], :pointer
|
85
|
+
attach_function :lua_pushnumber, [ :pointer, :float ], :pointer
|
86
|
+
attach_function :lua_pushstring, [ :pointer, :string ], :pointer
|
87
|
+
|
88
|
+
attach_function :lua_rawgeti, [ :pointer, :int, :int ], :void
|
89
|
+
|
90
|
+
attach_function :luaL_newstate, [], :pointer
|
91
|
+
attach_function :luaL_loadbuffer, [ :pointer, :string, :int, :string ], :int
|
92
|
+
attach_function :luaL_ref, [ :pointer, :int ], :int
|
93
|
+
attach_function :luaL_unref, [ :pointer, :int, :int ], :void
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
@@ -0,0 +1,246 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2009, John Mettraux, jmettraux@gmail.com
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
5
|
+
# of this software and associated documentation files (the "Software"), to deal
|
6
|
+
# in the Software without restriction, including without limitation the rights
|
7
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
+
# copies of the Software, and to permit persons to whom the Software is
|
9
|
+
# furnished to do so, subject to the following conditions:
|
10
|
+
#
|
11
|
+
# The above copyright notice and this permission notice shall be included in
|
12
|
+
# all copies or substantial portions of the Software.
|
13
|
+
#
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
15
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
16
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
17
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
18
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
19
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
20
|
+
# THE SOFTWARE.
|
21
|
+
#
|
22
|
+
# Made in Japan.
|
23
|
+
#++
|
24
|
+
|
25
|
+
|
26
|
+
module Rufus::Lua
|
27
|
+
|
28
|
+
#
|
29
|
+
# The parent class for Table, Function and Coroutine. Simply holds
|
30
|
+
# a reference to the object in the Lua registry.
|
31
|
+
#
|
32
|
+
class Ref
|
33
|
+
include StateMixin
|
34
|
+
|
35
|
+
#
|
36
|
+
# The reference in the Lua registry.
|
37
|
+
# (You shouldn't care about this value)
|
38
|
+
#
|
39
|
+
attr_reader :ref
|
40
|
+
|
41
|
+
def initialize (pointer)
|
42
|
+
@pointer = pointer
|
43
|
+
@ref = Lib.luaL_ref(@pointer, LUA_REGISTRYINDEX)
|
44
|
+
end
|
45
|
+
|
46
|
+
#
|
47
|
+
# Frees the reference to this object
|
48
|
+
# (Problably a good idea if you want Lua's GC to get rid of it later).
|
49
|
+
#
|
50
|
+
def free
|
51
|
+
Lib.luaL_unref(@pointer, LUA_REGISTRYINDEX, @ref)
|
52
|
+
@ref = nil
|
53
|
+
end
|
54
|
+
|
55
|
+
protected
|
56
|
+
|
57
|
+
#
|
58
|
+
# Brings the referenced object on top of the stack (will probably
|
59
|
+
# then take part in a method call).
|
60
|
+
#
|
61
|
+
def load_onto_stack
|
62
|
+
|
63
|
+
raise LuaError.new(
|
64
|
+
"#{self.class} got freed, cannot re-access it directly"
|
65
|
+
) unless @ref
|
66
|
+
|
67
|
+
stack_load_ref(@ref)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
#
|
72
|
+
# A Lua function.
|
73
|
+
#
|
74
|
+
# require 'rubygems'
|
75
|
+
# require 'rufus/lua'
|
76
|
+
#
|
77
|
+
# s = Rufus::Lua::State.new
|
78
|
+
#
|
79
|
+
# f = s.eval(%{
|
80
|
+
# return function (x)
|
81
|
+
# return 2 * x
|
82
|
+
# end
|
83
|
+
# })
|
84
|
+
#
|
85
|
+
# f.call(2) # => 4.0
|
86
|
+
#
|
87
|
+
class Function < Ref
|
88
|
+
|
89
|
+
#
|
90
|
+
# Calls the Lua function.
|
91
|
+
#
|
92
|
+
def call (*args)
|
93
|
+
|
94
|
+
bottom = stack_top
|
95
|
+
|
96
|
+
load_onto_stack
|
97
|
+
# load function on stack
|
98
|
+
|
99
|
+
args.each { |arg| stack_push(arg) }
|
100
|
+
# push arguments on stack
|
101
|
+
|
102
|
+
pcall(bottom, args.length)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
#
|
107
|
+
# (coming soon)
|
108
|
+
#
|
109
|
+
class Coroutine < Ref
|
110
|
+
|
111
|
+
#
|
112
|
+
# Resumes the coroutine
|
113
|
+
#
|
114
|
+
def resume (*args)
|
115
|
+
|
116
|
+
bottom = stack_top
|
117
|
+
|
118
|
+
fetch_library_method('coroutine.resume').load_onto_stack
|
119
|
+
|
120
|
+
load_onto_stack
|
121
|
+
args.each { |arg| stack_push(arg) }
|
122
|
+
|
123
|
+
pcall(bottom, args.length + 1)
|
124
|
+
end
|
125
|
+
|
126
|
+
#
|
127
|
+
# Returns the string status of the coroutine :
|
128
|
+
# suspended/running/dead/normal
|
129
|
+
#
|
130
|
+
def status
|
131
|
+
|
132
|
+
bottom = stack_top
|
133
|
+
|
134
|
+
fetch_library_method('coroutine.status').load_onto_stack
|
135
|
+
load_onto_stack
|
136
|
+
|
137
|
+
pcall(bottom, 1)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
#
|
142
|
+
# A Lua table.
|
143
|
+
#
|
144
|
+
# For now, the only thing you can do with it is cast it into a Hash or
|
145
|
+
# an Array (will raise an exception if casting to an Array is not possible).
|
146
|
+
#
|
147
|
+
# Note that direct manipulation of the Lua table (inside Lua) is not possible
|
148
|
+
# (as of now).
|
149
|
+
#
|
150
|
+
class Table < Ref
|
151
|
+
include Enumerable
|
152
|
+
|
153
|
+
#
|
154
|
+
# The classical 'each'.
|
155
|
+
#
|
156
|
+
# Note it cheats by first turning the table into a Ruby Hash and calling
|
157
|
+
# the each of that Hash instance (this way, the stack isn't involved
|
158
|
+
# in the iteration).
|
159
|
+
#
|
160
|
+
def each
|
161
|
+
|
162
|
+
return unless block_given?
|
163
|
+
self.to_h.each { |k, v| yield(k, v) }
|
164
|
+
end
|
165
|
+
|
166
|
+
#
|
167
|
+
# Returns the array of keys of this Table.
|
168
|
+
#
|
169
|
+
def keys
|
170
|
+
|
171
|
+
self.to_h.keys
|
172
|
+
end
|
173
|
+
|
174
|
+
#
|
175
|
+
# Returns the array of values in this Table.
|
176
|
+
#
|
177
|
+
def values
|
178
|
+
|
179
|
+
self.to_h.values
|
180
|
+
end
|
181
|
+
|
182
|
+
#
|
183
|
+
# Returns the value behind the key, or else nil.
|
184
|
+
#
|
185
|
+
def [] (k)
|
186
|
+
|
187
|
+
load_onto_stack # table
|
188
|
+
stack_push(k) # key
|
189
|
+
Lib.lua_gettable(@pointer, -2) # fetch val for key at top and table at -2
|
190
|
+
stack_pop
|
191
|
+
end
|
192
|
+
|
193
|
+
#--
|
194
|
+
# TODO : implement (maybe)
|
195
|
+
#
|
196
|
+
#def []= (k, v)
|
197
|
+
# raise 'not yet !'
|
198
|
+
#end
|
199
|
+
#++
|
200
|
+
|
201
|
+
#
|
202
|
+
# Returns a Ruby Hash instance representing this Lua table.
|
203
|
+
#
|
204
|
+
def to_h
|
205
|
+
|
206
|
+
load_onto_stack
|
207
|
+
|
208
|
+
table_pos = stack_top
|
209
|
+
|
210
|
+
Lib.lua_pushnil(@pointer)
|
211
|
+
|
212
|
+
h = {}
|
213
|
+
|
214
|
+
while Lib.lua_next(@pointer, table_pos) != 0 do
|
215
|
+
|
216
|
+
value = stack_fetch(-1)
|
217
|
+
key = stack_fetch(-2)
|
218
|
+
|
219
|
+
stack_unstack # leave key on top
|
220
|
+
|
221
|
+
h[key] = value
|
222
|
+
end
|
223
|
+
|
224
|
+
h
|
225
|
+
end
|
226
|
+
|
227
|
+
#
|
228
|
+
# Returns a Ruby Array instance representing this Lua table.
|
229
|
+
#
|
230
|
+
# Will raise an error if the 'rendering' is not possible.
|
231
|
+
#
|
232
|
+
def to_a
|
233
|
+
|
234
|
+
h = self.to_h
|
235
|
+
|
236
|
+
keys = h.keys.sort
|
237
|
+
|
238
|
+
keys.find { |k| not [ Float ].include?(k.class) } &&
|
239
|
+
raise("cannot turn hash into array, some keys are not numbers")
|
240
|
+
|
241
|
+
keys.inject([]) { |a, k| a << h[k]; a }
|
242
|
+
end
|
243
|
+
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
@@ -0,0 +1,367 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2009, John Mettraux, jmettraux@gmail.com
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
5
|
+
# of this software and associated documentation files (the "Software"), to deal
|
6
|
+
# in the Software without restriction, including without limitation the rights
|
7
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
+
# copies of the Software, and to permit persons to whom the Software is
|
9
|
+
# furnished to do so, subject to the following conditions:
|
10
|
+
#
|
11
|
+
# The above copyright notice and this permission notice shall be included in
|
12
|
+
# all copies or substantial portions of the Software.
|
13
|
+
#
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
15
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
16
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
17
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
18
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
19
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
20
|
+
# THE SOFTWARE.
|
21
|
+
#
|
22
|
+
# Made in Japan.
|
23
|
+
#++
|
24
|
+
|
25
|
+
|
26
|
+
module Rufus::Lua
|
27
|
+
|
28
|
+
#
|
29
|
+
# An error class for this gem/library.
|
30
|
+
#
|
31
|
+
class LuaError < RuntimeError; end
|
32
|
+
|
33
|
+
#
|
34
|
+
# Rufus::Lua::Lib contains all the raw C API Lua methods. The methods
|
35
|
+
# here are shared by all the rufus-lua classes that have to deal with
|
36
|
+
# a Lua state. They are protected since they aren't meant to be called
|
37
|
+
# directly.
|
38
|
+
#
|
39
|
+
# The entry point of rufus-lua is Rufus::Lua::State, look there.
|
40
|
+
#
|
41
|
+
module StateMixin
|
42
|
+
|
43
|
+
LUA_GLOBALSINDEX = -10002
|
44
|
+
LUA_ENVIRONINDEX = -10001
|
45
|
+
LUA_REGISTRYINDEX = -10000
|
46
|
+
LUA_NOREF = -2
|
47
|
+
LUA_REFNIL = -1
|
48
|
+
|
49
|
+
TNONE = -1
|
50
|
+
TNIL = 0
|
51
|
+
TBOOLEAN = 1
|
52
|
+
TLIGHTUSERDATA = 2
|
53
|
+
TNUMBER = 3
|
54
|
+
TSTRING = 4
|
55
|
+
TTABLE = 5
|
56
|
+
TFUNCTION = 6
|
57
|
+
TUSERDATA = 7
|
58
|
+
TTHREAD = 8
|
59
|
+
|
60
|
+
LUA_MULTRET = -1
|
61
|
+
|
62
|
+
protected
|
63
|
+
|
64
|
+
#
|
65
|
+
# This method is used to fetch/cache references to library methods like
|
66
|
+
# 'math.sin' or 'coroutine.resume'.
|
67
|
+
# The caching is done at the Lua state level (ie, all Lua objects available
|
68
|
+
# via the state share the cache.
|
69
|
+
#
|
70
|
+
# (Not sure yet about this yet)
|
71
|
+
#
|
72
|
+
def fetch_library_method (s)
|
73
|
+
|
74
|
+
if m = @pointer.__lib_method_cache[s]
|
75
|
+
m
|
76
|
+
else
|
77
|
+
@pointer.__lib_method_cache[s] = loadstring_and_call("return #{s}")
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
#
|
82
|
+
# This method holds the 'eval' mechanism.
|
83
|
+
#
|
84
|
+
def loadstring_and_call (s)
|
85
|
+
|
86
|
+
bottom = stack_top
|
87
|
+
|
88
|
+
err = Lib.luaL_loadbuffer(@pointer, s, Lib.strlen(s), 'line')
|
89
|
+
raise_if_error('eval:compile', err)
|
90
|
+
|
91
|
+
pcall(bottom, 0) # arg_count is set to 0
|
92
|
+
end
|
93
|
+
|
94
|
+
#
|
95
|
+
# Returns a string representation of the state's stack.
|
96
|
+
#
|
97
|
+
def stack_to_s
|
98
|
+
|
99
|
+
# warning : don't touch at stack[0]
|
100
|
+
|
101
|
+
s = (1..stack_top).inject([]) { |a, i|
|
102
|
+
type, tname = stack_type_at(i)
|
103
|
+
a << "#{i} : #{tname} (#{type})"
|
104
|
+
a
|
105
|
+
}.reverse.join("\n")
|
106
|
+
s += "\n" if s.length > 0
|
107
|
+
s
|
108
|
+
end
|
109
|
+
|
110
|
+
#
|
111
|
+
# Outputs the stack to the stdout
|
112
|
+
#
|
113
|
+
def print_stack (msg=nil)
|
114
|
+
|
115
|
+
puts "\n=stack= #{msg ? "(#{msg})" : ""}"
|
116
|
+
puts "top : #{stack_top}"
|
117
|
+
print stack_to_s
|
118
|
+
puts "= ="
|
119
|
+
end
|
120
|
+
|
121
|
+
#
|
122
|
+
# Returns the offset (int) of the top element of the stack.
|
123
|
+
#
|
124
|
+
def stack_top
|
125
|
+
|
126
|
+
Lib.lua_gettop(@pointer)
|
127
|
+
end
|
128
|
+
|
129
|
+
#
|
130
|
+
# Returns a pair type (int) and type name (string) of the element on top
|
131
|
+
# of the Lua state's stack. There is an optional pos paramter to peek
|
132
|
+
# at other elements of the stack.
|
133
|
+
#
|
134
|
+
def stack_type_at (pos=-1)
|
135
|
+
|
136
|
+
type = Lib.lua_type(@pointer, pos)
|
137
|
+
tname = Lib.lua_typename(@pointer, type)
|
138
|
+
|
139
|
+
[ type, tname ]
|
140
|
+
end
|
141
|
+
|
142
|
+
#
|
143
|
+
# Fetches the top value on the stack (or the one specified by the optional
|
144
|
+
# pos parameter), but does not 'pop' it.
|
145
|
+
#
|
146
|
+
def stack_fetch (pos=-1)
|
147
|
+
|
148
|
+
type, tname = stack_type_at(pos)
|
149
|
+
|
150
|
+
case type
|
151
|
+
|
152
|
+
when TNIL then nil
|
153
|
+
|
154
|
+
when TSTRING then Lib.lua_tolstring(@pointer, pos, nil)
|
155
|
+
when TBOOLEAN then (Lib.lua_toboolean(@pointer, pos) == 1)
|
156
|
+
when TNUMBER then Lib.lua_tonumber(@pointer, pos)
|
157
|
+
|
158
|
+
when TTABLE then Table.new(@pointer)
|
159
|
+
when TFUNCTION then Function.new(@pointer)
|
160
|
+
when TTHREAD then Coroutine.new(@pointer)
|
161
|
+
|
162
|
+
else tname
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
#
|
167
|
+
# Pops the top value of lua state's stack and returns it.
|
168
|
+
#
|
169
|
+
def stack_pop
|
170
|
+
|
171
|
+
r = stack_fetch
|
172
|
+
stack_unstack
|
173
|
+
r
|
174
|
+
end
|
175
|
+
|
176
|
+
#
|
177
|
+
# Makes sure the stack loses its top element (but doesn't return it).
|
178
|
+
#
|
179
|
+
def stack_unstack
|
180
|
+
|
181
|
+
new_top = stack_top - 1
|
182
|
+
new_top = 0 if new_top < 0
|
183
|
+
Lib.lua_settop(@pointer, new_top)
|
184
|
+
end
|
185
|
+
|
186
|
+
#
|
187
|
+
# Given a Ruby instance, will attempt to push it on the Lua stack.
|
188
|
+
#
|
189
|
+
def stack_push (o)
|
190
|
+
|
191
|
+
case o
|
192
|
+
|
193
|
+
when NilClass then Lib.lua_pushnil(@pointer)
|
194
|
+
|
195
|
+
when TrueClass then Lib.lua_pushboolean(@pointer, 1)
|
196
|
+
when FalseClass then Lib.lua_pushboolean(@pointer, 1)
|
197
|
+
|
198
|
+
when Fixnum then Lib.lua_pushinteger(@pointer, o)
|
199
|
+
when Float then Lib.lua_pushnumber(@pointer, o)
|
200
|
+
|
201
|
+
when String then Lib.lua_pushstring(@pointer, o)
|
202
|
+
|
203
|
+
#when Hash then ...
|
204
|
+
#when Array then ...
|
205
|
+
|
206
|
+
else raise(
|
207
|
+
ArgumentError.new(
|
208
|
+
"don't know how to pass Ruby instance of #{o.class} to Lua"))
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
#
|
213
|
+
# Loads a Lua global value on top of the stack
|
214
|
+
#
|
215
|
+
def stack_load_global (name)
|
216
|
+
|
217
|
+
Lib.lua_getfield(@pointer, LUA_GLOBALSINDEX, name)
|
218
|
+
end
|
219
|
+
|
220
|
+
#
|
221
|
+
# Loads the Lua object registered with the given ref on top of the stack
|
222
|
+
#
|
223
|
+
def stack_load_ref (ref)
|
224
|
+
|
225
|
+
Lib.lua_rawgeti(@pointer, LUA_REGISTRYINDEX, @ref)
|
226
|
+
end
|
227
|
+
|
228
|
+
#
|
229
|
+
# Returns the result of a function call or a coroutine.resume().
|
230
|
+
#
|
231
|
+
def return_result (stack_bottom)
|
232
|
+
|
233
|
+
count = stack_top - stack_bottom
|
234
|
+
|
235
|
+
return nil if count == 0
|
236
|
+
return stack_pop if count == 1
|
237
|
+
|
238
|
+
(1..count).collect { |pos| stack_pop }.reverse
|
239
|
+
end
|
240
|
+
|
241
|
+
#
|
242
|
+
# Assumes the Lua stack is loaded with a ref to a method and arg_count
|
243
|
+
# arguments (on top of the method), will then call that Lua method and
|
244
|
+
# return a result.
|
245
|
+
#
|
246
|
+
# Will raise an error in case of failure.
|
247
|
+
#
|
248
|
+
def pcall (stack_bottom, arg_count)
|
249
|
+
|
250
|
+
#err = Lib.lua_pcall(@pointer, 0, 1, 0)
|
251
|
+
# when there's only 1 return value, use LUA_MULTRET (-1) the
|
252
|
+
# rest of the time
|
253
|
+
|
254
|
+
err = Lib.lua_pcall(@pointer, arg_count, LUA_MULTRET, 0)
|
255
|
+
raise_if_error('eval:pcall', err)
|
256
|
+
|
257
|
+
return_result(stack_bottom)
|
258
|
+
end
|
259
|
+
|
260
|
+
#--
|
261
|
+
# Resumes a coroutine (that has been placed, under its arguments,
|
262
|
+
# on top of the stack).
|
263
|
+
#
|
264
|
+
#def do_resume (stack_bottom, arg_count)
|
265
|
+
# err = Lib.lua_resume(@pointer, arg_count)
|
266
|
+
# raise_if_error('eval:resume', err)
|
267
|
+
# return_result(stack_bottom)
|
268
|
+
#end
|
269
|
+
#++
|
270
|
+
|
271
|
+
#
|
272
|
+
# This method will raise an error with err > 0, else it will immediately
|
273
|
+
# return.
|
274
|
+
#
|
275
|
+
def raise_if_error (where, err)
|
276
|
+
|
277
|
+
return if err < 1
|
278
|
+
|
279
|
+
# TODO :
|
280
|
+
#
|
281
|
+
# LUA_ERRRUN: a runtime error.
|
282
|
+
# LUA_ERRMEM: memory allocation error. For such errors, Lua does not call
|
283
|
+
# the error handler function.
|
284
|
+
# LUA_ERRERR: error while running the error handler function.
|
285
|
+
|
286
|
+
s = Lib.lua_tolstring(@pointer, -1, nil)
|
287
|
+
Lib.lua_settop(@pointer, -2)
|
288
|
+
|
289
|
+
raise LuaError.new("#{where} : '#{s}' (#{err})")
|
290
|
+
end
|
291
|
+
|
292
|
+
#
|
293
|
+
# Given the name of a Lua global variable, will return its value (or nil
|
294
|
+
# if there is nothing bound under that name).
|
295
|
+
#
|
296
|
+
def get_global (name)
|
297
|
+
|
298
|
+
stack_load_global(name)
|
299
|
+
stack_pop
|
300
|
+
end
|
301
|
+
end
|
302
|
+
|
303
|
+
#
|
304
|
+
# A Lua state, wraps a Lua runtime.
|
305
|
+
#
|
306
|
+
# require 'rufus/lua'
|
307
|
+
# s = Rufus::Lua::State.new
|
308
|
+
# s.eval "a = 1 + 2"
|
309
|
+
#
|
310
|
+
# p s['a'] # => 3.0
|
311
|
+
#
|
312
|
+
class State
|
313
|
+
include StateMixin
|
314
|
+
|
315
|
+
#
|
316
|
+
# Instantiates a Lua state (runtime).
|
317
|
+
#
|
318
|
+
# Accepts an 'include_libs' optional arg. When set to true (the default,
|
319
|
+
# all the base Lua libs are loaded in the runtime.
|
320
|
+
#
|
321
|
+
def initialize (include_libs=true)
|
322
|
+
|
323
|
+
@pointer = Lib.luaL_newstate
|
324
|
+
|
325
|
+
Lib.luaL_openlibs(@pointer) if include_libs
|
326
|
+
|
327
|
+
#
|
328
|
+
# preparing library methods cache
|
329
|
+
|
330
|
+
class << @pointer
|
331
|
+
attr_reader :__lib_method_cache
|
332
|
+
end
|
333
|
+
@pointer.instance_variable_set(:@__lib_method_cache, {})
|
334
|
+
end
|
335
|
+
|
336
|
+
#
|
337
|
+
# Evaluates a piece (string) of Lua code within the state.
|
338
|
+
#
|
339
|
+
def eval (s)
|
340
|
+
|
341
|
+
loadstring_and_call(s)
|
342
|
+
end
|
343
|
+
|
344
|
+
#
|
345
|
+
# Returns a value set at the 'global' level in the state.
|
346
|
+
#
|
347
|
+
# state.eval('a = 1 + 2')
|
348
|
+
# puts state['a'] # => "3.0"
|
349
|
+
#
|
350
|
+
def [] (k)
|
351
|
+
|
352
|
+
k.index('.') ? self.eval("return #{k}") : get_global(k)
|
353
|
+
end
|
354
|
+
|
355
|
+
#
|
356
|
+
# Closes the state.
|
357
|
+
#
|
358
|
+
# It's probably a good idea (mem leaks) to close a Lua state once you're
|
359
|
+
# done with it.
|
360
|
+
#
|
361
|
+
def close
|
362
|
+
|
363
|
+
Lib.lua_close(@pointer)
|
364
|
+
end
|
365
|
+
end
|
366
|
+
end
|
367
|
+
|
@@ -0,0 +1,78 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2009, John Mettraux, jmettraux@gmail.com
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
5
|
+
# of this software and associated documentation files (the "Software"), to deal
|
6
|
+
# in the Software without restriction, including without limitation the rights
|
7
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
+
# copies of the Software, and to permit persons to whom the Software is
|
9
|
+
# furnished to do so, subject to the following conditions:
|
10
|
+
#
|
11
|
+
# The above copyright notice and this permission notice shall be included in
|
12
|
+
# all copies or substantial portions of the Software.
|
13
|
+
#
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
15
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
16
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
17
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
18
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
19
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
20
|
+
# THE SOFTWARE.
|
21
|
+
#
|
22
|
+
# Made in Japan.
|
23
|
+
#++
|
24
|
+
|
25
|
+
|
26
|
+
module Rufus::Lua
|
27
|
+
|
28
|
+
#--
|
29
|
+
# always make sure that the methods here are usable without the need
|
30
|
+
# to load liblua.dylib
|
31
|
+
#++
|
32
|
+
|
33
|
+
#
|
34
|
+
# Turns a Ruby instance into a Lua parseable string representation.
|
35
|
+
#
|
36
|
+
# Will raise an ArgumentError as soon as something else than a simple
|
37
|
+
# Ruby type (or Hash/Array) is passed.
|
38
|
+
#
|
39
|
+
# Rufus::Lua.to_lua_s({ 'a' => 'A', 'b' => 2})
|
40
|
+
# #
|
41
|
+
# # => '{ "a": "A", "b": 2 }'
|
42
|
+
#
|
43
|
+
def self.to_lua_s (o)
|
44
|
+
|
45
|
+
case o
|
46
|
+
|
47
|
+
when String then o.inspect
|
48
|
+
when Fixnum then o.to_s
|
49
|
+
when Float then o.to_s
|
50
|
+
when TrueClass then o.to_s
|
51
|
+
when FalseClass then o.to_s
|
52
|
+
|
53
|
+
when Hash then to_lua_table_s(o)
|
54
|
+
when Array then to_lua_table_s(o)
|
55
|
+
|
56
|
+
else raise(
|
57
|
+
ArgumentError.new(
|
58
|
+
"don't how to turning into a Lua string representation "+
|
59
|
+
"Ruby instances of class '#{o.class}'"))
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
#
|
64
|
+
# Turns a Ruby Array or Hash instance into a Lua parseable string
|
65
|
+
# representation.
|
66
|
+
#
|
67
|
+
def self.to_lua_table_s (o)
|
68
|
+
|
69
|
+
s = if o.is_a?(Array)
|
70
|
+
o.collect { |e| to_lua_s(e) }
|
71
|
+
else
|
72
|
+
o.collect { |k, v| "#{to_lua_s(k)}: #{to_lua_s(v)}" }
|
73
|
+
end
|
74
|
+
|
75
|
+
"{ #{s.join(', ')} }"
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
data/spec/spec.rb
ADDED
metadata
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rufus-lua
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- John Mettraux
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-03-16 00:00:00 +09:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: ffi
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0"
|
24
|
+
version:
|
25
|
+
description:
|
26
|
+
email: jmettraux@gmail.com
|
27
|
+
executables: []
|
28
|
+
|
29
|
+
extensions: []
|
30
|
+
|
31
|
+
extra_rdoc_files:
|
32
|
+
- README.txt
|
33
|
+
- CHANGELOG.txt
|
34
|
+
- CREDITS.txt
|
35
|
+
- LICENSE.txt
|
36
|
+
files:
|
37
|
+
- lib/rufus/lua/lib.rb
|
38
|
+
- lib/rufus/lua/objects.rb
|
39
|
+
- lib/rufus/lua/state.rb
|
40
|
+
- lib/rufus/lua/utils.rb
|
41
|
+
- lib/rufus/lua.rb
|
42
|
+
- lib/rufus-lua.rb
|
43
|
+
- CHANGELOG.txt
|
44
|
+
- CREDITS.txt
|
45
|
+
- LICENSE.txt
|
46
|
+
- README.txt
|
47
|
+
- TODO.txt
|
48
|
+
has_rdoc: true
|
49
|
+
homepage: http://rufus.rubyforge.org/
|
50
|
+
post_install_message:
|
51
|
+
rdoc_options: []
|
52
|
+
|
53
|
+
require_paths:
|
54
|
+
- lib
|
55
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
56
|
+
requirements:
|
57
|
+
- - ">="
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: "0"
|
60
|
+
version:
|
61
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
62
|
+
requirements:
|
63
|
+
- - ">="
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: "0"
|
66
|
+
version:
|
67
|
+
requirements:
|
68
|
+
- ffi
|
69
|
+
rubyforge_project: rufus
|
70
|
+
rubygems_version: 1.3.1
|
71
|
+
signing_key:
|
72
|
+
specification_version: 2
|
73
|
+
summary: ruby-ffi based bridge from Ruby to Lua
|
74
|
+
test_files:
|
75
|
+
- spec/spec.rb
|