rufus-lua 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|